blob: 2c5c5c357dc94c710bead0fd378ade4463737d1c [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"
fdorayf33fede2017-05-11 21:18:1029#include "base/test/scoped_task_environment.h"
[email protected]f36a8132011-09-02 18:36:3330#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3531#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3532#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0733#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3334#include "net/base/completion_callback.h"
Bence Békya25e3f72018-02-13 21:13:3935#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0736#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2537#include "net/base/load_timing_info.h"
38#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2439#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1540#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4041#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3142#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5243#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1544#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0645#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2146#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0847#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1148#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1649#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5350#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2451#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1252#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0053#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2954#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1955#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5756#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5257#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5658#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2459#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1360#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5361#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5762#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3863#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1964#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0765#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0066#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1967#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5168#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4669#include "net/log/test_net_log_entry.h"
70#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4071#include "net/proxy_resolution/mock_proxy_resolver.h"
72#include "net/proxy_resolution/proxy_config_service_fixed.h"
73#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0374#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4075#include "net/proxy_resolution/proxy_resolver.h"
76#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4477#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1578#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0379#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4780#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0281#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0782#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0483#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4484#include "net/socket/socket_test_util.h"
85#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0686#include "net/spdy/chromium/spdy_session.h"
87#include "net/spdy/chromium/spdy_session_pool.h"
88#include "net/spdy/chromium/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1489#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5790#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0391#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5792#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5493#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1194#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0195#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1096#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:4397#include "net/test/test_data_directory.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2998#include "net/third_party/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:2399#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44100#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06101#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18102#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52103#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15104#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27105#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52106
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37107#if defined(NTLM_PORTABLE)
108#include "base/base64.h"
109#include "net/ntlm/ntlm_test_data.h"
110#endif
111
robpercival214763f2016-07-01 23:27:01112using net::test::IsError;
113using net::test::IsOk;
114
[email protected]ad65a3e2013-12-25 18:18:01115using base::ASCIIToUTF16;
116
initial.commit586acc5fe2008-07-26 22:42:52117//-----------------------------------------------------------------------------
118
ttuttle859dc7a2015-04-23 19:42:29119namespace net {
120
[email protected]13c8a092010-07-29 06:15:44121namespace {
122
[email protected]42cba2fb2013-03-29 19:58:57123const base::string16 kBar(ASCIIToUTF16("bar"));
124const base::string16 kBar2(ASCIIToUTF16("bar2"));
125const base::string16 kBar3(ASCIIToUTF16("bar3"));
126const base::string16 kBaz(ASCIIToUTF16("baz"));
127const base::string16 kFirst(ASCIIToUTF16("first"));
128const base::string16 kFoo(ASCIIToUTF16("foo"));
129const base::string16 kFoo2(ASCIIToUTF16("foo2"));
130const base::string16 kFoo3(ASCIIToUTF16("foo3"));
131const base::string16 kFou(ASCIIToUTF16("fou"));
132const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57133const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44134
bnc2df4b522016-07-08 18:17:43135const char kAlternativeServiceHttpHeader[] =
136 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
137
ttuttle859dc7a2015-04-23 19:42:29138int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
139 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
140 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02141}
142
ttuttle859dc7a2015-04-23 19:42:29143int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
144 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
145 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02146}
147
ttuttle859dc7a2015-04-23 19:42:29148bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
149 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
150 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52151}
152
[email protected]f3da152d2012-06-02 01:00:57153// Takes in a Value created from a NetLogHttpResponseParameter, and returns
154// a JSONified list of headers as a single string. Uses single quotes instead
155// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27156bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57157 if (!params)
158 return false;
[email protected]ea5ef4c2013-06-13 22:50:27159 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57160 if (!params->GetList("headers", &header_list))
161 return false;
162 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34163 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28164 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57165 return true;
166}
167
[email protected]029c83b62013-01-24 05:28:20168// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
169// used.
ttuttle859dc7a2015-04-23 19:42:29170void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20171 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19172 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25173
[email protected]029c83b62013-01-24 05:28:20174 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
175 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
176
ttuttle859dc7a2015-04-23 19:42:29177 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20178 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25179
180 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25181
[email protected]3b23a222013-05-15 21:33:25182 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25183 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
184 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25185 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25186}
187
[email protected]029c83b62013-01-24 05:28:20188// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
189// used.
ttuttle859dc7a2015-04-23 19:42:29190void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25191 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20192 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19193 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20194
195 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
196 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
197
ttuttle859dc7a2015-04-23 19:42:29198 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
199 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20200 EXPECT_LE(load_timing_info.connect_timing.connect_end,
201 load_timing_info.send_start);
202
203 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20204
[email protected]3b23a222013-05-15 21:33:25205 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20206 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
207 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25208 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20209}
210
211// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
212// used.
ttuttle859dc7a2015-04-23 19:42:29213void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20214 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19215 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20216
ttuttle859dc7a2015-04-23 19:42:29217 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20218
219 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
220 EXPECT_LE(load_timing_info.proxy_resolve_start,
221 load_timing_info.proxy_resolve_end);
222 EXPECT_LE(load_timing_info.proxy_resolve_end,
223 load_timing_info.send_start);
224 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20225
[email protected]3b23a222013-05-15 21:33:25226 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20227 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
228 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25229 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20230}
231
232// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
233// used.
ttuttle859dc7a2015-04-23 19:42:29234void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20235 int connect_timing_flags) {
236 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19237 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20238
239 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
240 EXPECT_LE(load_timing_info.proxy_resolve_start,
241 load_timing_info.proxy_resolve_end);
242 EXPECT_LE(load_timing_info.proxy_resolve_end,
243 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29244 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
245 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20246 EXPECT_LE(load_timing_info.connect_timing.connect_end,
247 load_timing_info.send_start);
248
249 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20250
[email protected]3b23a222013-05-15 21:33:25251 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20252 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
253 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25254 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25255}
256
danakj1fd259a02016-04-16 03:17:09257std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42258 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34259 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14260}
261
xunjieli96f2a402017-06-05 17:24:27262class FailingProxyResolverFactory : public ProxyResolverFactory {
263 public:
264 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
265
266 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42267 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
268 std::unique_ptr<ProxyResolver>* result,
269 const CompletionCallback& callback,
270 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27271 return ERR_PAC_SCRIPT_FAILED;
272 }
273};
274
David Benjamin5cb91132018-04-06 05:54:49275class TestSSLConfigService : public SSLConfigService {
276 public:
277 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
278
279 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
280
281 private:
282 ~TestSSLConfigService() override = default;
283
284 SSLConfig config_;
285};
286
[email protected]448d4ca52012-03-04 04:12:23287} // namespace
288
bncd16676a2016-07-20 16:23:01289class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03290 public:
bncd16676a2016-07-20 16:23:01291 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03292 // Important to restore the per-pool limit first, since the pool limit must
293 // always be greater than group limit, and the tests reduce both limits.
294 ClientSocketPoolManager::set_max_sockets_per_pool(
295 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
296 ClientSocketPoolManager::set_max_sockets_per_group(
297 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
298 }
299
[email protected]e3ceb682011-06-28 23:55:46300 protected:
[email protected]23e482282013-06-14 16:08:02301 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15302 : ssl_(ASYNC, OK),
303 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03304 HttpNetworkSession::NORMAL_SOCKET_POOL)),
305 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
306 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28307 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03308 }
[email protected]bb88e1d32013-05-03 23:11:07309
[email protected]e3ceb682011-06-28 23:55:46310 struct SimpleGetHelperResult {
311 int rv;
312 std::string status_line;
313 std::string response_data;
sclittlefb249892015-09-10 21:33:22314 int64_t total_received_bytes;
315 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25316 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47317 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59318 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46319 };
320
dcheng67be2b1f2014-10-27 21:47:29321 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50322 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55323 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54324 }
325
dcheng67be2b1f2014-10-27 21:47:29326 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50327 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55328 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09329 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55330 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09331 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50332 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55333 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09334 }
335
[email protected]202965992011-12-07 23:04:51336 // Either |write_failure| specifies a write failure or |read_failure|
337 // specifies a read failure when using a reused socket. In either case, the
338 // failure should cause the network transaction to resend the request, and the
339 // other argument should be NULL.
340 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
341 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52342
[email protected]a34f61ee2014-03-18 20:59:49343 // Either |write_failure| specifies a write failure or |read_failure|
344 // specifies a read failure when using a reused socket. In either case, the
345 // failure should cause the network transaction to resend the request, and the
346 // other argument should be NULL.
347 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10348 const MockRead* read_failure,
349 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49350
Ryan Sleevib8d7ea02018-05-07 20:01:01351 SimpleGetHelperResult SimpleGetHelperForData(
352 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15353 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52354
[email protected]ff007e162009-05-23 09:13:15355 HttpRequestInfo request;
356 request.method = "GET";
bncce36dca22015-04-21 22:11:23357 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10358 request.traffic_annotation =
359 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52360
vishal.b62985ca92015-04-17 08:45:51361 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07362 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09363 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27365
Ryan Sleevib8d7ea02018-05-07 20:01:01366 for (auto* provider : providers) {
367 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29368 }
initial.commit586acc5fe2008-07-26 22:42:52369
[email protected]49639fa2011-12-20 23:22:41370 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52371
eroman24bc6a12015-05-06 19:55:48372 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16373 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52375
[email protected]ff007e162009-05-23 09:13:15376 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16377 out.total_received_bytes = trans.GetTotalReceivedBytes();
378 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25379
380 // Even in the failure cases that use this function, connections are always
381 // successfully established before the error.
bnc691fda62016-08-12 00:43:16382 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25383 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
384
[email protected]ff007e162009-05-23 09:13:15385 if (out.rv != OK)
386 return out;
387
bnc691fda62016-08-12 00:43:16388 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50389 // Can't use ASSERT_* inside helper functions like this, so
390 // return an error.
wezca1070932016-05-26 20:30:52391 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50392 out.rv = ERR_UNEXPECTED;
393 return out;
394 }
[email protected]ff007e162009-05-23 09:13:15395 out.status_line = response->headers->GetStatusLine();
396
[email protected]80a09a82012-11-16 17:40:06397 EXPECT_EQ("127.0.0.1", response->socket_address.host());
398 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19399
ttuttled9dbc652015-09-29 20:00:59400 bool got_endpoint =
bnc691fda62016-08-12 00:43:16401 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59402 EXPECT_EQ(got_endpoint,
403 out.remote_endpoint_after_start.address().size() > 0);
404
bnc691fda62016-08-12 00:43:16405 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01406 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40407
mmenke43758e62015-05-04 21:09:46408 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40409 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39410 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00411 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
412 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39413 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00414 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
415 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15416
[email protected]f3da152d2012-06-02 01:00:57417 std::string line;
418 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
419 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
420
[email protected]79e1fd62013-06-20 06:50:04421 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16422 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04423 std::string value;
424 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23425 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04426 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
427 EXPECT_EQ("keep-alive", value);
428
429 std::string response_headers;
430 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23431 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04432 response_headers);
[email protected]3deb9a52010-11-11 00:24:40433
bnc691fda62016-08-12 00:43:16434 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22435 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16436 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22437
bnc691fda62016-08-12 00:43:16438 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47439 return out;
[email protected]ff007e162009-05-23 09:13:15440 }
initial.commit586acc5fe2008-07-26 22:42:52441
Ryan Sleevib8d7ea02018-05-07 20:01:01442 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22443 MockWrite data_writes[] = {
444 MockWrite("GET / HTTP/1.1\r\n"
445 "Host: www.example.org\r\n"
446 "Connection: keep-alive\r\n\r\n"),
447 };
[email protected]5a60c8b2011-10-19 20:14:29448
Ryan Sleevib8d7ea02018-05-07 20:01:01449 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22450 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01451 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22452
Ryan Sleevib8d7ea02018-05-07 20:01:01453 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22454 return out;
[email protected]b8015c42013-12-24 15:18:19455 }
456
bnc032658ba2016-09-26 18:17:15457 void AddSSLSocketData() {
458 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49459 ssl_.ssl_info.cert =
460 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
461 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
463 }
464
[email protected]ff007e162009-05-23 09:13:15465 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
466 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52467
[email protected]ff007e162009-05-23 09:13:15468 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07469
[email protected]bb88e1d32013-05-03 23:11:07470 void CheckErrorIsPassedBack(int error, IoMode mode);
471
[email protected]4bd46222013-05-14 19:32:23472 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07473 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15474 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03475
476 // Original socket limits. Some tests set these. Safest to always restore
477 // them once each test has been run.
478 int old_max_group_sockets_;
479 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15480};
[email protected]231d5a32008-09-13 00:45:27481
[email protected]448d4ca52012-03-04 04:12:23482namespace {
483
ryansturm49a8cb12016-06-15 16:51:09484class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27485 public:
ryansturm49a8cb12016-06-15 16:51:09486 BeforeHeadersSentHandler()
487 : observed_before_headers_sent_with_proxy_(false),
488 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27489
ryansturm49a8cb12016-06-15 16:51:09490 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
491 HttpRequestHeaders* request_headers) {
492 observed_before_headers_sent_ = true;
493 if (!proxy_info.is_http() && !proxy_info.is_https() &&
494 !proxy_info.is_quic()) {
495 return;
496 }
497 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27498 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
499 }
500
ryansturm49a8cb12016-06-15 16:51:09501 bool observed_before_headers_sent_with_proxy() const {
502 return observed_before_headers_sent_with_proxy_;
503 }
504
505 bool observed_before_headers_sent() const {
506 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27507 }
508
509 std::string observed_proxy_server_uri() const {
510 return observed_proxy_server_uri_;
511 }
512
513 private:
ryansturm49a8cb12016-06-15 16:51:09514 bool observed_before_headers_sent_with_proxy_;
515 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27516 std::string observed_proxy_server_uri_;
517
ryansturm49a8cb12016-06-15 16:51:09518 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27519};
520
[email protected]15a5ccf82008-10-23 19:57:43521// Fill |str| with a long header list that consumes >= |size| bytes.
522void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51523 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19524 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
525 const int sizeof_row = strlen(row);
526 const int num_rows = static_cast<int>(
527 ceil(static_cast<float>(size) / sizeof_row));
528 const int sizeof_data = num_rows * sizeof_row;
529 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43530 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51531
[email protected]4ddaf2502008-10-23 18:26:19532 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43533 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19534}
535
thakis84dff942015-07-28 20:47:38536#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09537uint64_t MockGetMSTime() {
538 // Tue, 23 May 2017 20:13:07 +0000
539 return 131400439870000000;
540}
541
[email protected]385a4672009-03-11 22:21:29542// Alternative functions that eliminate randomness and dependency on the local
543// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37544void MockGenerateRandom(uint8_t* output, size_t n) {
545 // This is set to 0xaa because the client challenge for testing in
546 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
547 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29548}
549
[email protected]fe2bc6a2009-03-23 16:52:20550std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37551 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29552}
thakis84dff942015-07-28 20:47:38553#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29554
[email protected]e60e47a2010-07-14 03:37:18555template<typename ParentPool>
556class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31557 public:
[email protected]9e1bdd32011-02-03 21:48:34558 CaptureGroupNameSocketPool(HostResolver* host_resolver,
559 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18560
[email protected]d80a4322009-08-14 07:07:49561 const std::string last_group_name_received() const {
562 return last_group_name_;
563 }
564
Tarun Bansal162eabe52018-01-20 01:16:39565 bool socket_requested() const { return socket_requested_; }
566
dmichaeld6e570d2014-12-18 22:30:57567 int RequestSocket(const std::string& group_name,
568 const void* socket_params,
569 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54570 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15571 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57572 ClientSocketHandle* handle,
573 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20574 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31575 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39576 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31577 return ERR_IO_PENDING;
578 }
dmichaeld6e570d2014-12-18 22:30:57579 void CancelRequest(const std::string& group_name,
580 ClientSocketHandle* handle) override {}
581 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09582 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57583 int id) override {}
584 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23585 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57586 int IdleSocketCount() const override { return 0; }
587 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31588 return 0;
589 }
dmichaeld6e570d2014-12-18 22:30:57590 LoadState GetLoadState(const std::string& group_name,
591 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31592 return LOAD_STATE_IDLE;
593 }
dmichaeld6e570d2014-12-18 22:30:57594 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26595 return base::TimeDelta();
596 }
[email protected]d80a4322009-08-14 07:07:49597
598 private:
[email protected]04e5be32009-06-26 20:00:31599 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39600 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31601};
602
[email protected]ab739042011-04-07 15:22:28603typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
604CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13605typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
606CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06607typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11608CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18609typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
610CaptureGroupNameSSLSocketPool;
611
rkaplowd90695c2015-03-25 22:12:41612template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18613CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34614 HostResolver* host_resolver,
615 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21616 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18617
hashimoto0d3e4fb2015-01-09 05:02:50618template <>
[email protected]2df19bb2010-08-25 20:13:46619CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21620 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34621 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09622 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46623
[email protected]007b3f82013-04-09 08:46:45624template <>
[email protected]e60e47a2010-07-14 03:37:18625CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21626 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34627 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45628 : SSLClientSocketPool(0,
629 0,
[email protected]007b3f82013-04-09 08:46:45630 cert_verifier,
631 NULL,
632 NULL,
[email protected]284303b62013-11-28 15:11:54633 NULL,
eranm6571b2b2014-12-03 15:53:23634 NULL,
[email protected]007b3f82013-04-09 08:46:45635 std::string(),
636 NULL,
637 NULL,
638 NULL,
639 NULL,
640 NULL,
[email protected]8e458552014-08-05 00:02:15641 NULL) {
642}
[email protected]2227c692010-05-04 15:36:11643
[email protected]231d5a32008-09-13 00:45:27644//-----------------------------------------------------------------------------
645
[email protected]79cb5c12011-09-12 13:12:04646// Helper functions for validating that AuthChallengeInfo's are correctly
647// configured for common cases.
648bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
649 if (!auth_challenge)
650 return false;
651 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43652 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04653 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19654 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04655 return true;
656}
657
658bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
659 if (!auth_challenge)
660 return false;
661 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43662 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
663 EXPECT_EQ("MyRealm1", auth_challenge->realm);
664 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
665 return true;
666}
667
668bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
669 if (!auth_challenge)
670 return false;
671 EXPECT_TRUE(auth_challenge->is_proxy);
672 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04673 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19674 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04675 return true;
676}
677
678bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
679 if (!auth_challenge)
680 return false;
681 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43682 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04683 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19684 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04685 return true;
686}
687
thakis84dff942015-07-28 20:47:38688#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04689bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
690 if (!auth_challenge)
691 return false;
692 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55693 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04694 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19695 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04696 return true;
697}
David Benjamin5cb91132018-04-06 05:54:49698
699bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
700 if (!auth_challenge)
701 return false;
702 EXPECT_TRUE(auth_challenge->is_proxy);
703 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
704 EXPECT_EQ(std::string(), auth_challenge->realm);
705 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
706 return true;
707}
thakis84dff942015-07-28 20:47:38708#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04709
[email protected]448d4ca52012-03-04 04:12:23710} // namespace
711
bncd16676a2016-07-20 16:23:01712TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27715}
716
bncd16676a2016-07-20 16:23:01717TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27718 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35719 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
720 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06721 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27722 };
Ryan Sleevib8d7ea02018-05-07 20:01:01723 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01724 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27725 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
726 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01727 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22728 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47729 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59730
731 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27732}
733
734// Response with no status line.
bncd16676a2016-07-20 16:23:01735TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27736 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35737 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06738 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27739 };
Ryan Sleevib8d7ea02018-05-07 20:01:01740 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41741 EXPECT_THAT(out.rv, IsOk());
742 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
743 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01744 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41745 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27746}
747
mmenkea7da6da2016-09-01 21:56:52748// Response with no status line, and a weird port. Should fail by default.
749TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
750 MockRead data_reads[] = {
751 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
752 };
753
Ryan Sleevib8d7ea02018-05-07 20:01:01754 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52755 session_deps_.socket_factory->AddSocketDataProvider(&data);
756
757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
758
krasinc06a72a2016-12-21 03:42:46759 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58760 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19761 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52762
mmenkea7da6da2016-09-01 21:56:52763 request.method = "GET";
764 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10765 request.traffic_annotation =
766 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
767
mmenkea7da6da2016-09-01 21:56:52768 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20769 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52770 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
771}
772
Shivani Sharmafdcaefd2017-11-02 00:12:26773// Tests that request info can be destroyed after the headers phase is complete.
774TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
776 auto trans =
777 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
778
779 MockRead data_reads[] = {
780 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
781 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
782 };
Ryan Sleevib8d7ea02018-05-07 20:01:01783 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26784 session_deps_.socket_factory->AddSocketDataProvider(&data);
785
786 TestCompletionCallback callback;
787
788 {
789 auto request = std::make_unique<HttpRequestInfo>();
790 request->method = "GET";
791 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10792 request->traffic_annotation =
793 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26794
795 int rv =
796 trans->Start(request.get(), callback.callback(), NetLogWithSource());
797
798 EXPECT_THAT(callback.GetResult(rv), IsOk());
799 } // Let request info be destroyed.
800
801 trans.reset();
802}
803
mmenkea7da6da2016-09-01 21:56:52804// Response with no status line, and a weird port. Option to allow weird ports
805// enabled.
806TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
807 MockRead data_reads[] = {
808 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
809 };
810
Ryan Sleevib8d7ea02018-05-07 20:01:01811 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52812 session_deps_.socket_factory->AddSocketDataProvider(&data);
813 session_deps_.http_09_on_non_default_ports_enabled = true;
814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
815
krasinc06a72a2016-12-21 03:42:46816 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58817 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19818 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52819
mmenkea7da6da2016-09-01 21:56:52820 request.method = "GET";
821 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10822 request.traffic_annotation =
823 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
824
mmenkea7da6da2016-09-01 21:56:52825 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20826 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52827 EXPECT_THAT(callback.GetResult(rv), IsOk());
828
829 const HttpResponseInfo* info = trans->GetResponseInfo();
830 ASSERT_TRUE(info->headers);
831 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
832
833 // Don't bother to read the body - that's verified elsewhere, important thing
834 // is that the option to allow HTTP/0.9 on non-default ports is respected.
835}
836
[email protected]231d5a32008-09-13 00:45:27837// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01838TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27839 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35840 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06841 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27842 };
Ryan Sleevib8d7ea02018-05-07 20:01:01843 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01844 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27845 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
846 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01847 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22848 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27849}
850
851// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01852TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27853 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35854 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06855 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27856 };
Ryan Sleevib8d7ea02018-05-07 20:01:01857 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01858 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27859 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
860 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01861 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22862 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27863}
864
865// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01866TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27867 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35868 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06869 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27870 };
Ryan Sleevib8d7ea02018-05-07 20:01:01871 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41872 EXPECT_THAT(out.rv, IsOk());
873 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
874 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01875 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41876 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27877}
878
879// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01880TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27881 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35882 MockRead("\n"),
883 MockRead("\n"),
884 MockRead("Q"),
885 MockRead("J"),
886 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06887 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27888 };
Ryan Sleevib8d7ea02018-05-07 20:01:01889 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01890 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27891 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
892 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01893 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22894 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27895}
896
897// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01898TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27899 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35900 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06901 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27902 };
Ryan Sleevib8d7ea02018-05-07 20:01:01903 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41904 EXPECT_THAT(out.rv, IsOk());
905 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
906 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01907 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41908 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52909}
910
[email protected]f9d44aa2008-09-23 23:57:17911// Simulate a 204 response, lacking a Content-Length header, sent over a
912// persistent connection. The response should still terminate since a 204
913// cannot have a response body.
bncd16676a2016-07-20 16:23:01914TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19915 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17916 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35917 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19918 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06919 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17920 };
Ryan Sleevib8d7ea02018-05-07 20:01:01921 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01922 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17923 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
924 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01925 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22926 int64_t response_size = reads_size - strlen(junk);
927 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17928}
929
[email protected]0877e3d2009-10-17 22:29:57930// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01931TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19932 std::string final_chunk = "0\r\n\r\n";
933 std::string extra_data = "HTTP/1.1 200 OK\r\n";
934 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57935 MockRead data_reads[] = {
936 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
937 MockRead("5\r\nHello\r\n"),
938 MockRead("1\r\n"),
939 MockRead(" \r\n"),
940 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19941 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06942 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57943 };
Ryan Sleevib8d7ea02018-05-07 20:01:01944 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01945 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:57946 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
947 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01948 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22949 int64_t response_size = reads_size - extra_data.size();
950 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57951}
952
[email protected]9fe44f52010-09-23 18:36:00953// Next tests deal with http://crbug.com/56344.
954
bncd16676a2016-07-20 16:23:01955TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00956 MultipleContentLengthHeadersNoTransferEncoding) {
957 MockRead data_reads[] = {
958 MockRead("HTTP/1.1 200 OK\r\n"),
959 MockRead("Content-Length: 10\r\n"),
960 MockRead("Content-Length: 5\r\n\r\n"),
961 };
Ryan Sleevib8d7ea02018-05-07 20:01:01962 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01963 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:00964}
965
bncd16676a2016-07-20 16:23:01966TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04967 DuplicateContentLengthHeadersNoTransferEncoding) {
968 MockRead data_reads[] = {
969 MockRead("HTTP/1.1 200 OK\r\n"),
970 MockRead("Content-Length: 5\r\n"),
971 MockRead("Content-Length: 5\r\n\r\n"),
972 MockRead("Hello"),
973 };
Ryan Sleevib8d7ea02018-05-07 20:01:01974 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01975 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04976 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
977 EXPECT_EQ("Hello", out.response_data);
978}
979
bncd16676a2016-07-20 16:23:01980TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04981 ComplexContentLengthHeadersNoTransferEncoding) {
982 // More than 2 dupes.
983 {
984 MockRead data_reads[] = {
985 MockRead("HTTP/1.1 200 OK\r\n"),
986 MockRead("Content-Length: 5\r\n"),
987 MockRead("Content-Length: 5\r\n"),
988 MockRead("Content-Length: 5\r\n\r\n"),
989 MockRead("Hello"),
990 };
Ryan Sleevib8d7ea02018-05-07 20:01:01991 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01992 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04993 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
994 EXPECT_EQ("Hello", out.response_data);
995 }
996 // HTTP/1.0
997 {
998 MockRead data_reads[] = {
999 MockRead("HTTP/1.0 200 OK\r\n"),
1000 MockRead("Content-Length: 5\r\n"),
1001 MockRead("Content-Length: 5\r\n"),
1002 MockRead("Content-Length: 5\r\n\r\n"),
1003 MockRead("Hello"),
1004 };
Ryan Sleevib8d7ea02018-05-07 20:01:011005 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011006 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041007 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1008 EXPECT_EQ("Hello", out.response_data);
1009 }
1010 // 2 dupes and one mismatched.
1011 {
1012 MockRead data_reads[] = {
1013 MockRead("HTTP/1.1 200 OK\r\n"),
1014 MockRead("Content-Length: 10\r\n"),
1015 MockRead("Content-Length: 10\r\n"),
1016 MockRead("Content-Length: 5\r\n\r\n"),
1017 };
Ryan Sleevib8d7ea02018-05-07 20:01:011018 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011019 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041020 }
1021}
1022
bncd16676a2016-07-20 16:23:011023TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001024 MultipleContentLengthHeadersTransferEncoding) {
1025 MockRead data_reads[] = {
1026 MockRead("HTTP/1.1 200 OK\r\n"),
1027 MockRead("Content-Length: 666\r\n"),
1028 MockRead("Content-Length: 1337\r\n"),
1029 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1030 MockRead("5\r\nHello\r\n"),
1031 MockRead("1\r\n"),
1032 MockRead(" \r\n"),
1033 MockRead("5\r\nworld\r\n"),
1034 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061035 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001036 };
Ryan Sleevib8d7ea02018-05-07 20:01:011037 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011038 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001039 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1040 EXPECT_EQ("Hello world", out.response_data);
1041}
1042
[email protected]1628fe92011-10-04 23:04:551043// Next tests deal with http://crbug.com/98895.
1044
1045// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011046TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551047 MockRead data_reads[] = {
1048 MockRead("HTTP/1.1 200 OK\r\n"),
1049 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1050 MockRead("Content-Length: 5\r\n\r\n"),
1051 MockRead("Hello"),
1052 };
Ryan Sleevib8d7ea02018-05-07 20:01:011053 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551055 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1056 EXPECT_EQ("Hello", out.response_data);
1057}
1058
[email protected]54a9c6e52012-03-21 20:10:591059// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011060TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551061 MockRead data_reads[] = {
1062 MockRead("HTTP/1.1 200 OK\r\n"),
1063 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1064 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1065 MockRead("Content-Length: 5\r\n\r\n"),
1066 MockRead("Hello"),
1067 };
Ryan Sleevib8d7ea02018-05-07 20:01:011068 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011069 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591070 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1071 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551072}
1073
1074// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011075TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551076 MockRead data_reads[] = {
1077 MockRead("HTTP/1.1 200 OK\r\n"),
1078 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1079 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1080 MockRead("Content-Length: 5\r\n\r\n"),
1081 MockRead("Hello"),
1082 };
Ryan Sleevib8d7ea02018-05-07 20:01:011083 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011084 EXPECT_THAT(out.rv,
1085 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551086}
1087
[email protected]54a9c6e52012-03-21 20:10:591088// Checks that two identical Location headers result in no error.
1089// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011090TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551091 MockRead data_reads[] = {
1092 MockRead("HTTP/1.1 302 Redirect\r\n"),
1093 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591094 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551095 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061096 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551097 };
1098
1099 HttpRequestInfo request;
1100 request.method = "GET";
1101 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101102 request.traffic_annotation =
1103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551104
danakj1fd259a02016-04-16 03:17:091105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161106 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551107
Ryan Sleevib8d7ea02018-05-07 20:01:011108 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551110
[email protected]49639fa2011-12-20 23:22:411111 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551112
tfarina42834112016-09-22 13:38:201113 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551115
robpercival214763f2016-07-01 23:27:011116 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551117
bnc691fda62016-08-12 00:43:161118 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521119 ASSERT_TRUE(response);
1120 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551121 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1122 std::string url;
1123 EXPECT_TRUE(response->headers->IsRedirect(&url));
1124 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471125 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551126}
1127
[email protected]1628fe92011-10-04 23:04:551128// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011129TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551130 MockRead data_reads[] = {
1131 MockRead("HTTP/1.1 302 Redirect\r\n"),
1132 MockRead("Location: http://good.com/\r\n"),
1133 MockRead("Location: http://evil.com/\r\n"),
1134 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061135 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551136 };
Ryan Sleevib8d7ea02018-05-07 20:01:011137 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551139}
1140
[email protected]ef0faf2e72009-03-05 23:27:231141// Do a request using the HEAD method. Verify that we don't try to read the
1142// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011143TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421144 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231145 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231146 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101147 request.traffic_annotation =
1148 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231149
danakj1fd259a02016-04-16 03:17:091150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091152 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161153 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091154 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1155 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271156
[email protected]ef0faf2e72009-03-05 23:27:231157 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131158 MockWrite("HEAD / HTTP/1.1\r\n"
1159 "Host: www.example.org\r\n"
1160 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231161 };
1162 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231163 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1164 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231165
mmenked39192ee2015-12-09 00:57:231166 // No response body because the test stops reading here.
1167 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231168 };
1169
Ryan Sleevib8d7ea02018-05-07 20:01:011170 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071171 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231172
[email protected]49639fa2011-12-20 23:22:411173 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231174
tfarina42834112016-09-22 13:38:201175 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231177
1178 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011179 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231180
bnc691fda62016-08-12 00:43:161181 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521182 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231183
1184 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521185 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231186 EXPECT_EQ(1234, response->headers->GetContentLength());
1187 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471188 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091189 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1190 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231191
1192 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101193 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231194 bool has_server_header = response->headers->EnumerateHeader(
1195 &iter, "Server", &server_header);
1196 EXPECT_TRUE(has_server_header);
1197 EXPECT_EQ("Blah", server_header);
1198
1199 // Reading should give EOF right away, since there is no message body
1200 // (despite non-zero content-length).
1201 std::string response_data;
bnc691fda62016-08-12 00:43:161202 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011203 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231204 EXPECT_EQ("", response_data);
1205}
1206
bncd16676a2016-07-20 16:23:011207TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091208 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521209
1210 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351211 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1212 MockRead("hello"),
1213 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1214 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061215 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521216 };
Ryan Sleevib8d7ea02018-05-07 20:01:011217 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071218 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521219
[email protected]0b0bf032010-09-21 18:08:501220 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521221 "hello", "world"
1222 };
1223
1224 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421225 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521226 request.method = "GET";
bncce36dca22015-04-21 22:11:231227 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101228 request.traffic_annotation =
1229 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521230
bnc691fda62016-08-12 00:43:161231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271232
[email protected]49639fa2011-12-20 23:22:411233 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521234
tfarina42834112016-09-22 13:38:201235 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521237
1238 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011239 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521240
bnc691fda62016-08-12 00:43:161241 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521242 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521243
wezca1070932016-05-26 20:30:521244 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251245 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471246 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521247
1248 std::string response_data;
bnc691fda62016-08-12 00:43:161249 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011250 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251251 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521252 }
1253}
1254
bncd16676a2016-07-20 16:23:011255TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091256 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221257 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191258 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221259 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271260
[email protected]1c773ea12009-04-28 19:58:421261 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521262 request.method = "POST";
1263 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271264 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101265 request.traffic_annotation =
1266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521267
shivanishab9a143952016-09-19 17:23:411268 // Check the upload progress returned before initialization is correct.
1269 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1270 EXPECT_EQ(0u, progress.size());
1271 EXPECT_EQ(0u, progress.position());
1272
danakj1fd259a02016-04-16 03:17:091273 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271275
initial.commit586acc5fe2008-07-26 22:42:521276 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351277 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1278 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1279 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061280 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521281 };
Ryan Sleevib8d7ea02018-05-07 20:01:011282 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071283 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521284
[email protected]49639fa2011-12-20 23:22:411285 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521286
tfarina42834112016-09-22 13:38:201287 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521289
1290 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011291 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521292
bnc691fda62016-08-12 00:43:161293 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521294 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521295
wezca1070932016-05-26 20:30:521296 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251297 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521298
1299 std::string response_data;
bnc691fda62016-08-12 00:43:161300 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011301 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251302 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521303}
1304
[email protected]3a2d3662009-03-27 03:49:141305// This test is almost the same as Ignores100 above, but the response contains
1306// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571307// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011308TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421309 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141310 request.method = "GET";
1311 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101312 request.traffic_annotation =
1313 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141314
danakj1fd259a02016-04-16 03:17:091315 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161316 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271317
[email protected]3a2d3662009-03-27 03:49:141318 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571319 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1320 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141321 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061322 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141323 };
Ryan Sleevib8d7ea02018-05-07 20:01:011324 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071325 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141326
[email protected]49639fa2011-12-20 23:22:411327 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141328
tfarina42834112016-09-22 13:38:201329 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011330 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141331
1332 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011333 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141334
bnc691fda62016-08-12 00:43:161335 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521336 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141337
wezca1070932016-05-26 20:30:521338 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141339 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1340
1341 std::string response_data;
bnc691fda62016-08-12 00:43:161342 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011343 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141344 EXPECT_EQ("hello world", response_data);
1345}
1346
bncd16676a2016-07-20 16:23:011347TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081348 HttpRequestInfo request;
1349 request.method = "POST";
1350 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101351 request.traffic_annotation =
1352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081353
danakj1fd259a02016-04-16 03:17:091354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081356
1357 MockRead data_reads[] = {
1358 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1359 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381360 };
Ryan Sleevib8d7ea02018-05-07 20:01:011361 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081362 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381363
zmo9528c9f42015-08-04 22:12:081364 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381365
tfarina42834112016-09-22 13:38:201366 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381368
zmo9528c9f42015-08-04 22:12:081369 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011370 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381371
zmo9528c9f42015-08-04 22:12:081372 std::string response_data;
bnc691fda62016-08-12 00:43:161373 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011374 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081375 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381376}
1377
bncd16676a2016-07-20 16:23:011378TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381379 HttpRequestInfo request;
1380 request.method = "POST";
1381 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101382 request.traffic_annotation =
1383 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381384
danakj1fd259a02016-04-16 03:17:091385 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161386 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271387
[email protected]ee9410e72010-01-07 01:42:381388 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061389 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381390 };
Ryan Sleevib8d7ea02018-05-07 20:01:011391 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071392 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381393
[email protected]49639fa2011-12-20 23:22:411394 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381395
tfarina42834112016-09-22 13:38:201396 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381398
1399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011400 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381401}
1402
[email protected]23e482282013-06-14 16:08:021403void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511404 const MockWrite* write_failure,
1405 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421406 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521407 request.method = "GET";
1408 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101409 request.traffic_annotation =
1410 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521411
vishal.b62985ca92015-04-17 08:45:511412 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071413 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091414 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271415
[email protected]202965992011-12-07 23:04:511416 // Written data for successfully sending both requests.
1417 MockWrite data1_writes[] = {
1418 MockWrite("GET / HTTP/1.1\r\n"
1419 "Host: www.foo.com\r\n"
1420 "Connection: keep-alive\r\n\r\n"),
1421 MockWrite("GET / HTTP/1.1\r\n"
1422 "Host: www.foo.com\r\n"
1423 "Connection: keep-alive\r\n\r\n")
1424 };
1425
1426 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521427 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351428 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1429 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061430 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521431 };
[email protected]202965992011-12-07 23:04:511432
1433 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491434 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511435 data1_writes[1] = *write_failure;
1436 } else {
1437 ASSERT_TRUE(read_failure);
1438 data1_reads[2] = *read_failure;
1439 }
1440
Ryan Sleevib8d7ea02018-05-07 20:01:011441 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071442 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521443
1444 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351445 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1446 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061447 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521448 };
Ryan Sleevib8d7ea02018-05-07 20:01:011449 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071450 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521451
thestig9d3bb0c2015-01-24 00:49:511452 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521453 "hello", "world"
1454 };
1455
mikecironef22f9812016-10-04 03:40:191456 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521457 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411458 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521459
bnc691fda62016-08-12 00:43:161460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521461
tfarina42834112016-09-22 13:38:201462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521464
1465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011466 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521467
[email protected]58e32bb2013-01-21 18:23:251468 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161469 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251470 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1471 if (i == 0) {
1472 first_socket_log_id = load_timing_info.socket_log_id;
1473 } else {
1474 // The second request should be using a new socket.
1475 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1476 }
1477
bnc691fda62016-08-12 00:43:161478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521479 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521480
wezca1070932016-05-26 20:30:521481 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471482 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251483 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521484
1485 std::string response_data;
bnc691fda62016-08-12 00:43:161486 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011487 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251488 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521489 }
1490}
[email protected]3d2a59b2008-09-26 19:44:251491
[email protected]a34f61ee2014-03-18 20:59:491492void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1493 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101494 const MockRead* read_failure,
1495 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491496 HttpRequestInfo request;
1497 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101498 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101499 request.traffic_annotation =
1500 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491501
vishal.b62985ca92015-04-17 08:45:511502 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491503 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491505
[email protected]09356c652014-03-25 15:36:101506 SSLSocketDataProvider ssl1(ASYNC, OK);
1507 SSLSocketDataProvider ssl2(ASYNC, OK);
1508 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361509 ssl1.next_proto = kProtoHTTP2;
1510 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101511 }
1512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491514
[email protected]09356c652014-03-25 15:36:101515 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411516 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491517 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411518 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151519 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411520 SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191521 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491522
[email protected]09356c652014-03-25 15:36:101523 // HTTP/1.1 versions of the request and response.
1524 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1525 "Host: www.foo.com\r\n"
1526 "Connection: keep-alive\r\n\r\n";
1527 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1528 const char kHttpData[] = "hello";
1529
1530 std::vector<MockRead> data1_reads;
1531 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491532 if (write_failure) {
1533 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101534 data1_writes.push_back(*write_failure);
1535 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491536 } else {
1537 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101538 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411539 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101540 } else {
1541 data1_writes.push_back(MockWrite(kHttpRequest));
1542 }
1543 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491544 }
1545
Ryan Sleevib8d7ea02018-05-07 20:01:011546 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491547 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1548
[email protected]09356c652014-03-25 15:36:101549 std::vector<MockRead> data2_reads;
1550 std::vector<MockWrite> data2_writes;
1551
1552 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411553 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101554
bncdf80d44fd2016-07-15 20:27:411555 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1556 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101557 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1558 } else {
1559 data2_writes.push_back(
1560 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1561
1562 data2_reads.push_back(
1563 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1564 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1565 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1566 }
Ryan Sleevib8d7ea02018-05-07 20:01:011567 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491568 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1569
1570 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591571 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491572 // Wait for the preconnect to complete.
1573 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1574 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101575 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491576
1577 // Make the request.
1578 TestCompletionCallback callback;
1579
bnc691fda62016-08-12 00:43:161580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491581
tfarina42834112016-09-22 13:38:201582 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491584
1585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011586 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491587
1588 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161589 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101590 TestLoadTimingNotReused(
1591 load_timing_info,
1592 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491593
bnc691fda62016-08-12 00:43:161594 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521595 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491596
wezca1070932016-05-26 20:30:521597 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021598 if (response->was_fetched_via_spdy) {
1599 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1600 } else {
1601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1602 }
[email protected]a34f61ee2014-03-18 20:59:491603
1604 std::string response_data;
bnc691fda62016-08-12 00:43:161605 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011606 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101607 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491608}
1609
Biljith Jayan45a41722017-08-16 18:43:141610// Test that we do not retry indefinitely when a server sends an error like
1611// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1612// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1613TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1614 HttpRequestInfo request;
1615 request.method = "GET";
1616 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101617 request.traffic_annotation =
1618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141619
1620 // Check whether we give up after the third try.
1621
1622 // Construct an HTTP2 request and a "Go away" response.
1623 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1624 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291625 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011626 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1627 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141628
1629 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011630 StaticSocketDataProvider data1(data_read1, data_write);
1631 StaticSocketDataProvider data2(data_read1, data_write);
1632 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141633
1634 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1635 AddSSLSocketData();
1636 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1637 AddSSLSocketData();
1638 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1639 AddSSLSocketData();
1640
1641 TestCompletionCallback callback;
1642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1644
1645 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1647
1648 rv = callback.WaitForResult();
1649 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1650}
1651
1652TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1653 HttpRequestInfo request;
1654 request.method = "GET";
1655 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101656 request.traffic_annotation =
1657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141658
1659 // Check whether we try atleast thrice before giving up.
1660
1661 // Construct an HTTP2 request and a "Go away" response.
1662 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1663 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291664 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011665 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1666 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141667
1668 // Construct a non error HTTP2 response.
1669 SpdySerializedFrame spdy_response_no_error(
1670 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1671 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1672 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1673 CreateMockRead(spdy_data, 2)};
1674
1675 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011676 StaticSocketDataProvider data1(data_read1, data_write);
1677 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141678 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011679 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141680
1681 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1682 AddSSLSocketData();
1683 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1684 AddSSLSocketData();
1685 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1686 AddSSLSocketData();
1687
1688 TestCompletionCallback callback;
1689 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1691
1692 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1694
1695 rv = callback.WaitForResult();
1696 EXPECT_THAT(rv, IsOk());
1697}
1698
bncd16676a2016-07-20 16:23:011699TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061700 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511701 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1702}
1703
bncd16676a2016-07-20 16:23:011704TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061705 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511706 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251707}
1708
bncd16676a2016-07-20 16:23:011709TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061710 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511711 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251712}
1713
[email protected]d58ceea82014-06-04 10:55:541714// Make sure that on a 408 response (Request Timeout), the request is retried,
1715// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011716TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541717 MockRead read_failure(SYNCHRONOUS,
1718 "HTTP/1.1 408 Request Timeout\r\n"
1719 "Connection: Keep-Alive\r\n"
1720 "Content-Length: 6\r\n\r\n"
1721 "Pickle");
1722 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1723}
1724
bncd16676a2016-07-20 16:23:011725TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491726 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101727 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491728}
1729
bncd16676a2016-07-20 16:23:011730TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491731 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101732 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491733}
1734
bncd16676a2016-07-20 16:23:011735TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491736 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101737 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1738}
1739
bncd16676a2016-07-20 16:23:011740TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101741 MockRead read_failure(ASYNC, OK); // EOF
1742 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1743}
1744
[email protected]d58ceea82014-06-04 10:55:541745// Make sure that on a 408 response (Request Timeout), the request is retried,
1746// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011747TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541748 MockRead read_failure(SYNCHRONOUS,
1749 "HTTP/1.1 408 Request Timeout\r\n"
1750 "Connection: Keep-Alive\r\n"
1751 "Content-Length: 6\r\n\r\n"
1752 "Pickle");
1753 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1754 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1755}
1756
bncd16676a2016-07-20 16:23:011757TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101758 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1759 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1760}
1761
bncd16676a2016-07-20 16:23:011762TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101763 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1764 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1765}
1766
bncd16676a2016-07-20 16:23:011767TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101768 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1769 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1770}
1771
bncd16676a2016-07-20 16:23:011772TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101773 MockRead read_failure(ASYNC, OK); // EOF
1774 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491775}
1776
bncd16676a2016-07-20 16:23:011777TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421778 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251779 request.method = "GET";
bncce36dca22015-04-21 22:11:231780 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101781 request.traffic_annotation =
1782 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251783
danakj1fd259a02016-04-16 03:17:091784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271786
[email protected]3d2a59b2008-09-26 19:44:251787 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061788 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351789 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1790 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061791 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251792 };
Ryan Sleevib8d7ea02018-05-07 20:01:011793 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071794 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251795
[email protected]49639fa2011-12-20 23:22:411796 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251797
tfarina42834112016-09-22 13:38:201798 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251800
1801 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011802 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591803
1804 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161805 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591806 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251807}
1808
1809// What do various browsers do when the server closes a non-keepalive
1810// connection without sending any response header or body?
1811//
1812// IE7: error page
1813// Safari 3.1.2 (Windows): error page
1814// Firefox 3.0.1: blank page
1815// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421816// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1817// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011818TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251819 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061820 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351821 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1822 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061823 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251824 };
Ryan Sleevib8d7ea02018-05-07 20:01:011825 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011826 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251827}
[email protected]1826a402014-01-08 15:40:481828
[email protected]7a5378b2012-11-04 03:25:171829// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1830// tests. There was a bug causing HttpNetworkTransaction to hang in the
1831// destructor in such situations.
1832// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011833TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171834 HttpRequestInfo request;
1835 request.method = "GET";
bncce36dca22015-04-21 22:11:231836 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101837 request.traffic_annotation =
1838 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171839
danakj1fd259a02016-04-16 03:17:091840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581841 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191842 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171843
1844 MockRead data_reads[] = {
1845 MockRead("HTTP/1.0 200 OK\r\n"),
1846 MockRead("Connection: keep-alive\r\n"),
1847 MockRead("Content-Length: 100\r\n\r\n"),
1848 MockRead("hello"),
1849 MockRead(SYNCHRONOUS, 0),
1850 };
Ryan Sleevib8d7ea02018-05-07 20:01:011851 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071852 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171853
1854 TestCompletionCallback callback;
1855
tfarina42834112016-09-22 13:38:201856 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171858
1859 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011860 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171861
1862 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501863 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171864 if (rv == ERR_IO_PENDING)
1865 rv = callback.WaitForResult();
1866 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501867 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011868 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171869
1870 trans.reset();
fdoray92e35a72016-06-10 15:54:551871 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171872 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1873}
1874
bncd16676a2016-07-20 16:23:011875TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171876 HttpRequestInfo request;
1877 request.method = "GET";
bncce36dca22015-04-21 22:11:231878 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101879 request.traffic_annotation =
1880 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171881
danakj1fd259a02016-04-16 03:17:091882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581883 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191884 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171885
1886 MockRead data_reads[] = {
1887 MockRead("HTTP/1.0 200 OK\r\n"),
1888 MockRead("Connection: keep-alive\r\n"),
1889 MockRead("Content-Length: 100\r\n\r\n"),
1890 MockRead(SYNCHRONOUS, 0),
1891 };
Ryan Sleevib8d7ea02018-05-07 20:01:011892 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071893 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171894
1895 TestCompletionCallback callback;
1896
tfarina42834112016-09-22 13:38:201897 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171899
1900 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011901 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171902
1903 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501904 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171905 if (rv == ERR_IO_PENDING)
1906 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011907 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171908
1909 trans.reset();
fdoray92e35a72016-06-10 15:54:551910 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171911 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1912}
1913
[email protected]0b0bf032010-09-21 18:08:501914// Test that we correctly reuse a keep-alive connection after not explicitly
1915// reading the body.
bncd16676a2016-07-20 16:23:011916TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131917 HttpRequestInfo request;
1918 request.method = "GET";
1919 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101920 request.traffic_annotation =
1921 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:131922
vishal.b62985ca92015-04-17 08:45:511923 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071924 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091925 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271926
mmenkecc2298e2015-12-07 18:20:181927 const char* request_data =
1928 "GET / HTTP/1.1\r\n"
1929 "Host: www.foo.com\r\n"
1930 "Connection: keep-alive\r\n\r\n";
1931 MockWrite data_writes[] = {
1932 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1933 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1934 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1935 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1936 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1937 };
1938
[email protected]0b0bf032010-09-21 18:08:501939 // Note that because all these reads happen in the same
1940 // StaticSocketDataProvider, it shows that the same socket is being reused for
1941 // all transactions.
mmenkecc2298e2015-12-07 18:20:181942 MockRead data_reads[] = {
1943 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1944 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1945 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1946 MockRead(ASYNC, 7,
1947 "HTTP/1.1 302 Found\r\n"
1948 "Content-Length: 0\r\n\r\n"),
1949 MockRead(ASYNC, 9,
1950 "HTTP/1.1 302 Found\r\n"
1951 "Content-Length: 5\r\n\r\n"
1952 "hello"),
1953 MockRead(ASYNC, 11,
1954 "HTTP/1.1 301 Moved Permanently\r\n"
1955 "Content-Length: 0\r\n\r\n"),
1956 MockRead(ASYNC, 13,
1957 "HTTP/1.1 301 Moved Permanently\r\n"
1958 "Content-Length: 5\r\n\r\n"
1959 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131960
mmenkecc2298e2015-12-07 18:20:181961 // In the next two rounds, IsConnectedAndIdle returns false, due to
1962 // the set_busy_before_sync_reads(true) call, while the
1963 // HttpNetworkTransaction is being shut down, but the socket is still
1964 // reuseable. See http://crbug.com/544255.
1965 MockRead(ASYNC, 15,
1966 "HTTP/1.1 200 Hunky-Dory\r\n"
1967 "Content-Length: 5\r\n\r\n"),
1968 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131969
mmenkecc2298e2015-12-07 18:20:181970 MockRead(ASYNC, 18,
1971 "HTTP/1.1 200 Hunky-Dory\r\n"
1972 "Content-Length: 5\r\n\r\n"
1973 "he"),
1974 MockRead(SYNCHRONOUS, 19, "llo"),
1975
1976 // The body of the final request is actually read.
1977 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1978 MockRead(ASYNC, 22, "hello"),
1979 };
Ryan Sleevib8d7ea02018-05-07 20:01:011980 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:181981 data.set_busy_before_sync_reads(true);
1982 session_deps_.socket_factory->AddSocketDataProvider(&data);
1983
1984 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501985 std::string response_lines[kNumUnreadBodies];
1986
mikecironef22f9812016-10-04 03:40:191987 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181988 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411989 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131990
Jeremy Roman0579ed62017-08-29 15:56:191991 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:581992 session.get());
[email protected]fc31d6a42010-06-24 18:05:131993
tfarina42834112016-09-22 13:38:201994 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011995 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131996
[email protected]58e32bb2013-01-21 18:23:251997 LoadTimingInfo load_timing_info;
1998 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1999 if (i == 0) {
2000 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2001 first_socket_log_id = load_timing_info.socket_log_id;
2002 } else {
2003 TestLoadTimingReused(load_timing_info);
2004 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2005 }
2006
[email protected]fc31d6a42010-06-24 18:05:132007 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182008 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132009
mmenkecc2298e2015-12-07 18:20:182010 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502011 response_lines[i] = response->headers->GetStatusLine();
2012
mmenkecc2298e2015-12-07 18:20:182013 // Delete the transaction without reading the response bodies. Then spin
2014 // the message loop, so the response bodies are drained.
2015 trans.reset();
2016 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132017 }
[email protected]0b0bf032010-09-21 18:08:502018
2019 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182020 "HTTP/1.1 204 No Content",
2021 "HTTP/1.1 205 Reset Content",
2022 "HTTP/1.1 304 Not Modified",
2023 "HTTP/1.1 302 Found",
2024 "HTTP/1.1 302 Found",
2025 "HTTP/1.1 301 Moved Permanently",
2026 "HTTP/1.1 301 Moved Permanently",
2027 "HTTP/1.1 200 Hunky-Dory",
2028 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502029 };
2030
mostynb91e0da982015-01-20 19:17:272031 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2032 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502033
2034 for (int i = 0; i < kNumUnreadBodies; ++i)
2035 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2036
[email protected]49639fa2011-12-20 23:22:412037 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162038 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202039 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012040 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162041 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182042 ASSERT_TRUE(response);
2043 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502044 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2045 std::string response_data;
bnc691fda62016-08-12 00:43:162046 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012047 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502048 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132049}
2050
mmenke5f94fda2016-06-02 20:54:132051// Sockets that receive extra data after a response is complete should not be
2052// reused.
bncd16676a2016-07-20 16:23:012053TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132054 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2055 MockWrite data_writes1[] = {
2056 MockWrite("HEAD / HTTP/1.1\r\n"
2057 "Host: www.borked.com\r\n"
2058 "Connection: keep-alive\r\n\r\n"),
2059 };
2060
2061 MockRead data_reads1[] = {
2062 MockRead("HTTP/1.1 200 OK\r\n"
2063 "Connection: keep-alive\r\n"
2064 "Content-Length: 22\r\n\r\n"
2065 "This server is borked."),
2066 };
2067
2068 MockWrite data_writes2[] = {
2069 MockWrite("GET /foo HTTP/1.1\r\n"
2070 "Host: www.borked.com\r\n"
2071 "Connection: keep-alive\r\n\r\n"),
2072 };
2073
2074 MockRead data_reads2[] = {
2075 MockRead("HTTP/1.1 200 OK\r\n"
2076 "Content-Length: 3\r\n\r\n"
2077 "foo"),
2078 };
Ryan Sleevib8d7ea02018-05-07 20:01:012079 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132080 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012081 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132082 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2083
2084 TestCompletionCallback callback;
2085 HttpRequestInfo request1;
2086 request1.method = "HEAD";
2087 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102088 request1.traffic_annotation =
2089 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132090
bnc87dcefc2017-05-25 12:47:582091 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192092 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202093 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012094 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132095
2096 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2097 ASSERT_TRUE(response1);
2098 ASSERT_TRUE(response1->headers);
2099 EXPECT_EQ(200, response1->headers->response_code());
2100 EXPECT_TRUE(response1->headers->IsKeepAlive());
2101
2102 std::string response_data1;
robpercival214763f2016-07-01 23:27:012103 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132104 EXPECT_EQ("", response_data1);
2105 // Deleting the transaction attempts to release the socket back into the
2106 // socket pool.
2107 trans1.reset();
2108
2109 HttpRequestInfo request2;
2110 request2.method = "GET";
2111 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102112 request2.traffic_annotation =
2113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132114
bnc87dcefc2017-05-25 12:47:582115 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192116 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202117 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012118 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132119
2120 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2121 ASSERT_TRUE(response2);
2122 ASSERT_TRUE(response2->headers);
2123 EXPECT_EQ(200, response2->headers->response_code());
2124
2125 std::string response_data2;
robpercival214763f2016-07-01 23:27:012126 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132127 EXPECT_EQ("foo", response_data2);
2128}
2129
bncd16676a2016-07-20 16:23:012130TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2132 MockWrite data_writes1[] = {
2133 MockWrite("GET / HTTP/1.1\r\n"
2134 "Host: www.borked.com\r\n"
2135 "Connection: keep-alive\r\n\r\n"),
2136 };
2137
2138 MockRead data_reads1[] = {
2139 MockRead("HTTP/1.1 200 OK\r\n"
2140 "Connection: keep-alive\r\n"
2141 "Content-Length: 22\r\n\r\n"
2142 "This server is borked."
2143 "Bonus data!"),
2144 };
2145
2146 MockWrite data_writes2[] = {
2147 MockWrite("GET /foo HTTP/1.1\r\n"
2148 "Host: www.borked.com\r\n"
2149 "Connection: keep-alive\r\n\r\n"),
2150 };
2151
2152 MockRead data_reads2[] = {
2153 MockRead("HTTP/1.1 200 OK\r\n"
2154 "Content-Length: 3\r\n\r\n"
2155 "foo"),
2156 };
Ryan Sleevib8d7ea02018-05-07 20:01:012157 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132158 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012159 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132160 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2161
2162 TestCompletionCallback callback;
2163 HttpRequestInfo request1;
2164 request1.method = "GET";
2165 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102166 request1.traffic_annotation =
2167 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132168
bnc87dcefc2017-05-25 12:47:582169 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192170 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202171 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012172 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132173
2174 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2175 ASSERT_TRUE(response1);
2176 ASSERT_TRUE(response1->headers);
2177 EXPECT_EQ(200, response1->headers->response_code());
2178 EXPECT_TRUE(response1->headers->IsKeepAlive());
2179
2180 std::string response_data1;
robpercival214763f2016-07-01 23:27:012181 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132182 EXPECT_EQ("This server is borked.", response_data1);
2183 // Deleting the transaction attempts to release the socket back into the
2184 // socket pool.
2185 trans1.reset();
2186
2187 HttpRequestInfo request2;
2188 request2.method = "GET";
2189 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102190 request2.traffic_annotation =
2191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132192
bnc87dcefc2017-05-25 12:47:582193 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192194 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202195 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012196 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132197
2198 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2199 ASSERT_TRUE(response2);
2200 ASSERT_TRUE(response2->headers);
2201 EXPECT_EQ(200, response2->headers->response_code());
2202
2203 std::string response_data2;
robpercival214763f2016-07-01 23:27:012204 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132205 EXPECT_EQ("foo", response_data2);
2206}
2207
bncd16676a2016-07-20 16:23:012208TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132209 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2210 MockWrite data_writes1[] = {
2211 MockWrite("GET / HTTP/1.1\r\n"
2212 "Host: www.borked.com\r\n"
2213 "Connection: keep-alive\r\n\r\n"),
2214 };
2215
2216 MockRead data_reads1[] = {
2217 MockRead("HTTP/1.1 200 OK\r\n"
2218 "Connection: keep-alive\r\n"
2219 "Transfer-Encoding: chunked\r\n\r\n"),
2220 MockRead("16\r\nThis server is borked.\r\n"),
2221 MockRead("0\r\n\r\nBonus data!"),
2222 };
2223
2224 MockWrite data_writes2[] = {
2225 MockWrite("GET /foo HTTP/1.1\r\n"
2226 "Host: www.borked.com\r\n"
2227 "Connection: keep-alive\r\n\r\n"),
2228 };
2229
2230 MockRead data_reads2[] = {
2231 MockRead("HTTP/1.1 200 OK\r\n"
2232 "Content-Length: 3\r\n\r\n"
2233 "foo"),
2234 };
Ryan Sleevib8d7ea02018-05-07 20:01:012235 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132236 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012237 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132238 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2239
2240 TestCompletionCallback callback;
2241 HttpRequestInfo request1;
2242 request1.method = "GET";
2243 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102244 request1.traffic_annotation =
2245 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132246
bnc87dcefc2017-05-25 12:47:582247 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192248 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202249 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012250 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132251
2252 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2253 ASSERT_TRUE(response1);
2254 ASSERT_TRUE(response1->headers);
2255 EXPECT_EQ(200, response1->headers->response_code());
2256 EXPECT_TRUE(response1->headers->IsKeepAlive());
2257
2258 std::string response_data1;
robpercival214763f2016-07-01 23:27:012259 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132260 EXPECT_EQ("This server is borked.", response_data1);
2261 // Deleting the transaction attempts to release the socket back into the
2262 // socket pool.
2263 trans1.reset();
2264
2265 HttpRequestInfo request2;
2266 request2.method = "GET";
2267 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102268 request2.traffic_annotation =
2269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132270
bnc87dcefc2017-05-25 12:47:582271 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192272 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202273 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012274 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132275
2276 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2277 ASSERT_TRUE(response2);
2278 ASSERT_TRUE(response2->headers);
2279 EXPECT_EQ(200, response2->headers->response_code());
2280
2281 std::string response_data2;
robpercival214763f2016-07-01 23:27:012282 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132283 EXPECT_EQ("foo", response_data2);
2284}
2285
2286// This is a little different from the others - it tests the case that the
2287// HttpStreamParser doesn't know if there's extra data on a socket or not when
2288// the HttpNetworkTransaction is torn down, because the response body hasn't
2289// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012290TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2292 MockWrite data_writes1[] = {
2293 MockWrite("GET / HTTP/1.1\r\n"
2294 "Host: www.borked.com\r\n"
2295 "Connection: keep-alive\r\n\r\n"),
2296 };
2297
2298 MockRead data_reads1[] = {
2299 MockRead("HTTP/1.1 200 OK\r\n"
2300 "Connection: keep-alive\r\n"
2301 "Transfer-Encoding: chunked\r\n\r\n"),
2302 MockRead("16\r\nThis server is borked.\r\n"),
2303 MockRead("0\r\n\r\nBonus data!"),
2304 };
Ryan Sleevib8d7ea02018-05-07 20:01:012305 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132306 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2307
2308 TestCompletionCallback callback;
2309 HttpRequestInfo request1;
2310 request1.method = "GET";
2311 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102312 request1.traffic_annotation =
2313 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132314
bnc87dcefc2017-05-25 12:47:582315 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192316 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582317 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012318 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132319
bnc87dcefc2017-05-25 12:47:582320 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132321 ASSERT_TRUE(response1);
2322 ASSERT_TRUE(response1->headers);
2323 EXPECT_EQ(200, response1->headers->response_code());
2324 EXPECT_TRUE(response1->headers->IsKeepAlive());
2325
2326 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2327 // response body.
bnc87dcefc2017-05-25 12:47:582328 trans.reset();
mmenke5f94fda2016-06-02 20:54:132329
2330 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2331 // socket can't be reused, rather than returning it to the socket pool.
2332 base::RunLoop().RunUntilIdle();
2333
2334 // There should be no idle sockets in the pool.
2335 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2336}
2337
[email protected]038e9a32008-10-08 22:40:162338// Test the request-challenge-retry sequence for basic auth.
2339// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012340TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422341 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162342 request.method = "GET";
bncce36dca22015-04-21 22:11:232343 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102344 request.traffic_annotation =
2345 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162346
vishal.b62985ca92015-04-17 08:45:512347 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072348 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092349 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162350 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272351
[email protected]f9ee6b52008-11-08 06:46:232352 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232353 MockWrite(
2354 "GET / HTTP/1.1\r\n"
2355 "Host: www.example.org\r\n"
2356 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232357 };
2358
[email protected]038e9a32008-10-08 22:40:162359 MockRead data_reads1[] = {
2360 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2361 // Give a couple authenticate options (only the middle one is actually
2362 // supported).
[email protected]22927ad2009-09-21 19:56:192363 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162364 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2365 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2366 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2367 // Large content-length -- won't matter, as connection will be reset.
2368 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062369 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162370 };
2371
2372 // After calling trans->RestartWithAuth(), this is the request we should
2373 // be issuing -- the final header line contains the credentials.
2374 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232375 MockWrite(
2376 "GET / HTTP/1.1\r\n"
2377 "Host: www.example.org\r\n"
2378 "Connection: keep-alive\r\n"
2379 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162380 };
2381
2382 // Lastly, the server responds with the actual content.
2383 MockRead data_reads2[] = {
2384 MockRead("HTTP/1.0 200 OK\r\n"),
2385 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2386 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062387 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162388 };
2389
Ryan Sleevib8d7ea02018-05-07 20:01:012390 StaticSocketDataProvider data1(data_reads1, data_writes1);
2391 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072392 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2393 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162394
[email protected]49639fa2011-12-20 23:22:412395 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162396
tfarina42834112016-09-22 13:38:202397 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162399
2400 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012401 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162402
[email protected]58e32bb2013-01-21 18:23:252403 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162404 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252405 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2406
Ryan Sleevib8d7ea02018-05-07 20:01:012407 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162408 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012409 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162410 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192411
bnc691fda62016-08-12 00:43:162412 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522413 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042414 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162415
[email protected]49639fa2011-12-20 23:22:412416 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162417
bnc691fda62016-08-12 00:43:162418 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162420
2421 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012422 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162423
[email protected]58e32bb2013-01-21 18:23:252424 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162425 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252426 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2427 // The load timing after restart should have a new socket ID, and times after
2428 // those of the first load timing.
2429 EXPECT_LE(load_timing_info1.receive_headers_end,
2430 load_timing_info2.connect_timing.connect_start);
2431 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2432
Ryan Sleevib8d7ea02018-05-07 20:01:012433 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162434 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012435 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162436 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192437
bnc691fda62016-08-12 00:43:162438 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522439 ASSERT_TRUE(response);
2440 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162441 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162442}
2443
ttuttled9dbc652015-09-29 20:00:592444// Test the request-challenge-retry sequence for basic auth.
2445// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012446TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592447 HttpRequestInfo request;
2448 request.method = "GET";
2449 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102450 request.traffic_annotation =
2451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592452
2453 TestNetLog log;
2454 MockHostResolver* resolver = new MockHostResolver();
2455 session_deps_.net_log = &log;
2456 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092457 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592459
2460 resolver->rules()->ClearRules();
2461 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2462
2463 MockWrite data_writes1[] = {
2464 MockWrite("GET / HTTP/1.1\r\n"
2465 "Host: www.example.org\r\n"
2466 "Connection: keep-alive\r\n\r\n"),
2467 };
2468
2469 MockRead data_reads1[] = {
2470 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2471 // Give a couple authenticate options (only the middle one is actually
2472 // supported).
2473 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2474 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2475 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2476 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2477 // Large content-length -- won't matter, as connection will be reset.
2478 MockRead("Content-Length: 10000\r\n\r\n"),
2479 MockRead(SYNCHRONOUS, ERR_FAILED),
2480 };
2481
2482 // After calling trans->RestartWithAuth(), this is the request we should
2483 // be issuing -- the final header line contains the credentials.
2484 MockWrite data_writes2[] = {
2485 MockWrite("GET / HTTP/1.1\r\n"
2486 "Host: www.example.org\r\n"
2487 "Connection: keep-alive\r\n"
2488 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2489 };
2490
2491 // Lastly, the server responds with the actual content.
2492 MockRead data_reads2[] = {
2493 MockRead("HTTP/1.0 200 OK\r\n"),
2494 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2495 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2496 };
2497
Ryan Sleevib8d7ea02018-05-07 20:01:012498 StaticSocketDataProvider data1(data_reads1, data_writes1);
2499 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592500 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2501 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2502
2503 TestCompletionCallback callback1;
2504
bnc691fda62016-08-12 00:43:162505 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202506 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592507
2508 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162509 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592510 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2511
Ryan Sleevib8d7ea02018-05-07 20:01:012512 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162513 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012514 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162515 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592516
bnc691fda62016-08-12 00:43:162517 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592518 ASSERT_TRUE(response);
2519 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2520
2521 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162522 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592523 ASSERT_FALSE(endpoint.address().empty());
2524 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2525
2526 resolver->rules()->ClearRules();
2527 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2528
2529 TestCompletionCallback callback2;
2530
bnc691fda62016-08-12 00:43:162531 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592532 AuthCredentials(kFoo, kBar), callback2.callback())));
2533
2534 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162535 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592536 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2537 // The load timing after restart should have a new socket ID, and times after
2538 // those of the first load timing.
2539 EXPECT_LE(load_timing_info1.receive_headers_end,
2540 load_timing_info2.connect_timing.connect_start);
2541 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2542
Ryan Sleevib8d7ea02018-05-07 20:01:012543 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162544 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012545 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162546 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592547
bnc691fda62016-08-12 00:43:162548 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592549 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522550 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592551 EXPECT_EQ(100, response->headers->GetContentLength());
2552
bnc691fda62016-08-12 00:43:162553 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592554 ASSERT_FALSE(endpoint.address().empty());
2555 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2556}
2557
David Benjamin83ddfb32018-03-30 01:07:522558// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2559// will eventually give up.
2560TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2561 HttpRequestInfo request;
2562 request.method = "GET";
2563 request.url = GURL("http://www.example.org/");
2564 request.traffic_annotation =
2565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2566
2567 TestNetLog log;
2568 session_deps_.net_log = &log;
2569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2571
2572 MockWrite data_writes[] = {
2573 MockWrite("GET / HTTP/1.1\r\n"
2574 "Host: www.example.org\r\n"
2575 "Connection: keep-alive\r\n\r\n"),
2576 };
2577
2578 MockRead data_reads[] = {
2579 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2580 // Give a couple authenticate options (only the middle one is actually
2581 // supported).
2582 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2583 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2584 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2585 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2586 // Large content-length -- won't matter, as connection will be reset.
2587 MockRead("Content-Length: 10000\r\n\r\n"),
2588 MockRead(SYNCHRONOUS, ERR_FAILED),
2589 };
2590
2591 // After calling trans->RestartWithAuth(), this is the request we should
2592 // be issuing -- the final header line contains the credentials.
2593 MockWrite data_writes_restart[] = {
2594 MockWrite("GET / HTTP/1.1\r\n"
2595 "Host: www.example.org\r\n"
2596 "Connection: keep-alive\r\n"
2597 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2598 };
2599
Ryan Sleevib8d7ea02018-05-07 20:01:012600 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522601 session_deps_.socket_factory->AddSocketDataProvider(&data);
2602
2603 TestCompletionCallback callback;
2604 int rv = callback.GetResult(
2605 trans.Start(&request, callback.callback(), NetLogWithSource()));
2606
2607 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2608 for (int i = 0; i < 32; i++) {
2609 // Check the previous response was a 401.
2610 EXPECT_THAT(rv, IsOk());
2611 const HttpResponseInfo* response = trans.GetResponseInfo();
2612 ASSERT_TRUE(response);
2613 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2614
2615 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012616 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522617 session_deps_.socket_factory->AddSocketDataProvider(
2618 data_restarts.back().get());
2619 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2620 callback.callback()));
2621 }
2622
2623 // After too many tries, the transaction should have given up.
2624 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2625}
2626
bncd16676a2016-07-20 16:23:012627TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462628 HttpRequestInfo request;
2629 request.method = "GET";
bncce36dca22015-04-21 22:11:232630 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292631 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102632 request.traffic_annotation =
2633 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462634
danakj1fd259a02016-04-16 03:17:092635 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272637
[email protected]861fcd52009-08-26 02:33:462638 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232639 MockWrite(
2640 "GET / HTTP/1.1\r\n"
2641 "Host: www.example.org\r\n"
2642 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462643 };
2644
2645 MockRead data_reads[] = {
2646 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2647 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2648 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2649 // Large content-length -- won't matter, as connection will be reset.
2650 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062651 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462652 };
2653
Ryan Sleevib8d7ea02018-05-07 20:01:012654 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072655 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412656 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462657
tfarina42834112016-09-22 13:38:202658 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462660
2661 rv = callback.WaitForResult();
2662 EXPECT_EQ(0, rv);
2663
Ryan Sleevib8d7ea02018-05-07 20:01:012664 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162665 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012666 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162667 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192668
bnc691fda62016-08-12 00:43:162669 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522670 ASSERT_TRUE(response);
2671 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462672}
2673
[email protected]2d2697f92009-02-18 21:00:322674// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2675// connection.
bncd16676a2016-07-20 16:23:012676TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182677 // On the second pass, the body read of the auth challenge is synchronous, so
2678 // IsConnectedAndIdle returns false. The socket should still be drained and
2679 // reused. See http://crbug.com/544255.
2680 for (int i = 0; i < 2; ++i) {
2681 HttpRequestInfo request;
2682 request.method = "GET";
2683 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102684 request.traffic_annotation =
2685 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322686
mmenkecc2298e2015-12-07 18:20:182687 TestNetLog log;
2688 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092689 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272690
mmenkecc2298e2015-12-07 18:20:182691 MockWrite data_writes[] = {
2692 MockWrite(ASYNC, 0,
2693 "GET / HTTP/1.1\r\n"
2694 "Host: www.example.org\r\n"
2695 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322696
bnc691fda62016-08-12 00:43:162697 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182698 // be issuing -- the final header line contains the credentials.
2699 MockWrite(ASYNC, 6,
2700 "GET / HTTP/1.1\r\n"
2701 "Host: www.example.org\r\n"
2702 "Connection: keep-alive\r\n"
2703 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2704 };
[email protected]2d2697f92009-02-18 21:00:322705
mmenkecc2298e2015-12-07 18:20:182706 MockRead data_reads[] = {
2707 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2708 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2709 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2710 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2711 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322712
mmenkecc2298e2015-12-07 18:20:182713 // Lastly, the server responds with the actual content.
2714 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2715 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2716 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2717 MockRead(ASYNC, 10, "Hello"),
2718 };
[email protected]2d2697f92009-02-18 21:00:322719
Ryan Sleevib8d7ea02018-05-07 20:01:012720 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182721 data.set_busy_before_sync_reads(true);
2722 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462723
mmenkecc2298e2015-12-07 18:20:182724 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322725
bnc691fda62016-08-12 00:43:162726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202727 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012728 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322729
mmenkecc2298e2015-12-07 18:20:182730 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162731 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182732 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322733
bnc691fda62016-08-12 00:43:162734 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182735 ASSERT_TRUE(response);
2736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322737
mmenkecc2298e2015-12-07 18:20:182738 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252739
bnc691fda62016-08-12 00:43:162740 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2741 callback2.callback());
robpercival214763f2016-07-01 23:27:012742 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322743
mmenkecc2298e2015-12-07 18:20:182744 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162745 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182746 TestLoadTimingReused(load_timing_info2);
2747 // The load timing after restart should have the same socket ID, and times
2748 // those of the first load timing.
2749 EXPECT_LE(load_timing_info1.receive_headers_end,
2750 load_timing_info2.send_start);
2751 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322752
bnc691fda62016-08-12 00:43:162753 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182754 ASSERT_TRUE(response);
2755 EXPECT_FALSE(response->auth_challenge);
2756 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322757
mmenkecc2298e2015-12-07 18:20:182758 std::string response_data;
bnc691fda62016-08-12 00:43:162759 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322760
Ryan Sleevib8d7ea02018-05-07 20:01:012761 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162762 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012763 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162764 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182765 }
[email protected]2d2697f92009-02-18 21:00:322766}
2767
2768// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2769// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012770TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422771 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322772 request.method = "GET";
bncce36dca22015-04-21 22:11:232773 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102774 request.traffic_annotation =
2775 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322776
danakj1fd259a02016-04-16 03:17:092777 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272778
[email protected]2d2697f92009-02-18 21:00:322779 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162780 MockWrite("GET / HTTP/1.1\r\n"
2781 "Host: www.example.org\r\n"
2782 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322783
bnc691fda62016-08-12 00:43:162784 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232785 // be issuing -- the final header line contains the credentials.
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"
2789 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322790 };
2791
[email protected]2d2697f92009-02-18 21:00:322792 MockRead data_reads1[] = {
2793 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2794 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312795 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322796
2797 // Lastly, the server responds with the actual content.
2798 MockRead("HTTP/1.1 200 OK\r\n"),
2799 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502800 MockRead("Content-Length: 5\r\n\r\n"),
2801 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322802 };
2803
[email protected]2d0a4f92011-05-05 16:38:462804 // An incorrect reconnect would cause this to be read.
2805 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062806 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462807 };
2808
Ryan Sleevib8d7ea02018-05-07 20:01:012809 StaticSocketDataProvider data1(data_reads1, data_writes1);
2810 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072811 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2812 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322813
[email protected]49639fa2011-12-20 23:22:412814 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322815
bnc691fda62016-08-12 00:43:162816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202817 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322819
2820 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012821 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322822
bnc691fda62016-08-12 00:43:162823 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522824 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042825 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322826
[email protected]49639fa2011-12-20 23:22:412827 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322828
bnc691fda62016-08-12 00:43:162829 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322831
2832 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012833 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322834
bnc691fda62016-08-12 00:43:162835 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522836 ASSERT_TRUE(response);
2837 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502838 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322839}
2840
2841// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2842// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012843TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422844 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322845 request.method = "GET";
bncce36dca22015-04-21 22:11:232846 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102847 request.traffic_annotation =
2848 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322849
danakj1fd259a02016-04-16 03:17:092850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272851
[email protected]2d2697f92009-02-18 21:00:322852 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162853 MockWrite("GET / HTTP/1.1\r\n"
2854 "Host: www.example.org\r\n"
2855 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322856
bnc691fda62016-08-12 00:43:162857 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232858 // be issuing -- the final header line contains the credentials.
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"
2862 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322863 };
2864
2865 // Respond with 5 kb of response body.
2866 std::string large_body_string("Unauthorized");
2867 large_body_string.append(5 * 1024, ' ');
2868 large_body_string.append("\r\n");
2869
2870 MockRead data_reads1[] = {
2871 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2872 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2873 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2874 // 5134 = 12 + 5 * 1024 + 2
2875 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062876 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322877
2878 // Lastly, the server responds with the actual content.
2879 MockRead("HTTP/1.1 200 OK\r\n"),
2880 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502881 MockRead("Content-Length: 5\r\n\r\n"),
2882 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322883 };
2884
[email protected]2d0a4f92011-05-05 16:38:462885 // An incorrect reconnect would cause this to be read.
2886 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062887 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462888 };
2889
Ryan Sleevib8d7ea02018-05-07 20:01:012890 StaticSocketDataProvider data1(data_reads1, data_writes1);
2891 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072892 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2893 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322894
[email protected]49639fa2011-12-20 23:22:412895 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322896
bnc691fda62016-08-12 00:43:162897 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202898 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322900
2901 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012902 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322903
bnc691fda62016-08-12 00:43:162904 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522905 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042906 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322907
[email protected]49639fa2011-12-20 23:22:412908 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322909
bnc691fda62016-08-12 00:43:162910 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322912
2913 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012914 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322915
bnc691fda62016-08-12 00:43:162916 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522917 ASSERT_TRUE(response);
2918 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502919 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322920}
2921
2922// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312923// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012924TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312925 HttpRequestInfo request;
2926 request.method = "GET";
bncce36dca22015-04-21 22:11:232927 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102928 request.traffic_annotation =
2929 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:312930
danakj1fd259a02016-04-16 03:17:092931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272932
[email protected]11203f012009-11-12 23:02:312933 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232934 MockWrite(
2935 "GET / HTTP/1.1\r\n"
2936 "Host: www.example.org\r\n"
2937 "Connection: keep-alive\r\n\r\n"),
2938 // This simulates the seemingly successful write to a closed connection
2939 // if the bug is not fixed.
2940 MockWrite(
2941 "GET / HTTP/1.1\r\n"
2942 "Host: www.example.org\r\n"
2943 "Connection: keep-alive\r\n"
2944 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312945 };
2946
2947 MockRead data_reads1[] = {
2948 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2949 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2950 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2951 MockRead("Content-Length: 14\r\n\r\n"),
2952 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062953 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312954 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062955 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312956 };
2957
bnc691fda62016-08-12 00:43:162958 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312959 // be issuing -- the final header line contains the credentials.
2960 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232961 MockWrite(
2962 "GET / HTTP/1.1\r\n"
2963 "Host: www.example.org\r\n"
2964 "Connection: keep-alive\r\n"
2965 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312966 };
2967
2968 // Lastly, the server responds with the actual content.
2969 MockRead data_reads2[] = {
2970 MockRead("HTTP/1.1 200 OK\r\n"),
2971 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502972 MockRead("Content-Length: 5\r\n\r\n"),
2973 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312974 };
2975
Ryan Sleevib8d7ea02018-05-07 20:01:012976 StaticSocketDataProvider data1(data_reads1, data_writes1);
2977 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072978 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2979 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312980
[email protected]49639fa2011-12-20 23:22:412981 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312982
bnc691fda62016-08-12 00:43:162983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202984 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312986
2987 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012988 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312989
bnc691fda62016-08-12 00:43:162990 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522991 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042992 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312993
[email protected]49639fa2011-12-20 23:22:412994 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312995
bnc691fda62016-08-12 00:43:162996 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312998
2999 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013000 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313001
bnc691fda62016-08-12 00:43:163002 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523003 ASSERT_TRUE(response);
3004 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503005 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313006}
3007
[email protected]394816e92010-08-03 07:38:593008// Test the request-challenge-retry sequence for basic auth, over a connection
3009// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013010TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013011 HttpRequestInfo request;
3012 request.method = "GET";
bncce36dca22015-04-21 22:11:233013 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013014 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293015 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103016 request.traffic_annotation =
3017 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013018
3019 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593020 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493021 ProxyResolutionService::CreateFixedFromPacResult(
3022 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513023 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013024 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093025 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013026
3027 // Since we have proxy, should try to establish tunnel.
3028 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543029 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173030 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543031 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013032 };
3033
mmenkee71e15332015-10-07 16:39:543034 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013035 // connection.
3036 MockRead data_reads1[] = {
3037 // No credentials.
3038 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3039 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543040 };
ttuttle34f63b52015-03-05 04:33:013041
mmenkee71e15332015-10-07 16:39:543042 // Since the first connection couldn't be reused, need to establish another
3043 // once given credentials.
3044 MockWrite data_writes2[] = {
3045 // After calling trans->RestartWithAuth(), this is the request we should
3046 // be issuing -- the final header line contains the credentials.
3047 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173048 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543049 "Proxy-Connection: keep-alive\r\n"
3050 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3051
3052 MockWrite("GET / HTTP/1.1\r\n"
3053 "Host: www.example.org\r\n"
3054 "Connection: keep-alive\r\n\r\n"),
3055 };
3056
3057 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013058 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3059
3060 MockRead("HTTP/1.1 200 OK\r\n"),
3061 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3062 MockRead("Content-Length: 5\r\n\r\n"),
3063 MockRead(SYNCHRONOUS, "hello"),
3064 };
3065
Ryan Sleevib8d7ea02018-05-07 20:01:013066 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013067 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013068 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543069 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013070 SSLSocketDataProvider ssl(ASYNC, OK);
3071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3072
3073 TestCompletionCallback callback1;
3074
bnc87dcefc2017-05-25 12:47:583075 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193076 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013077
3078 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013080
3081 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013082 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463083 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013084 log.GetEntries(&entries);
3085 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003086 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3087 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013088 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003089 entries, pos,
3090 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3091 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013092
3093 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523094 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013095 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523096 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013097 EXPECT_EQ(407, response->headers->response_code());
3098 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3099 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3100
3101 LoadTimingInfo load_timing_info;
3102 // CONNECT requests and responses are handled at the connect job level, so
3103 // the transaction does not yet have a connection.
3104 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3105
3106 TestCompletionCallback callback2;
3107
3108 rv =
3109 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013111
3112 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013113 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013114
3115 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523116 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013117
3118 EXPECT_TRUE(response->headers->IsKeepAlive());
3119 EXPECT_EQ(200, response->headers->response_code());
3120 EXPECT_EQ(5, response->headers->GetContentLength());
3121 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3122
3123 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523124 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013125
3126 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3127 TestLoadTimingNotReusedWithPac(load_timing_info,
3128 CONNECT_TIMING_HAS_SSL_TIMES);
3129
3130 trans.reset();
3131 session->CloseAllConnections();
3132}
3133
3134// Test the request-challenge-retry sequence for basic auth, over a connection
3135// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013136TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593137 HttpRequestInfo request;
3138 request.method = "GET";
bncce36dca22015-04-21 22:11:233139 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593140 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293141 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103142 request.traffic_annotation =
3143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593144
[email protected]cb9bf6ca2011-01-28 13:15:273145 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593146 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493147 ProxyResolutionService::CreateFixedFromPacResult(
3148 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513149 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073150 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093151 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273152
[email protected]394816e92010-08-03 07:38:593153 // Since we have proxy, should try to establish tunnel.
3154 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543155 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173156 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543157 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113158 };
3159
mmenkee71e15332015-10-07 16:39:543160 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083161 // connection.
3162 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543163 // No credentials.
3164 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3165 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3166 MockRead("Proxy-Connection: close\r\n\r\n"),
3167 };
mmenkee0b5c882015-08-26 20:29:113168
mmenkee71e15332015-10-07 16:39:543169 MockWrite data_writes2[] = {
3170 // After calling trans->RestartWithAuth(), this is the request we should
3171 // be issuing -- the final header line contains the credentials.
3172 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173173 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543174 "Proxy-Connection: keep-alive\r\n"
3175 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083176
mmenkee71e15332015-10-07 16:39:543177 MockWrite("GET / HTTP/1.1\r\n"
3178 "Host: www.example.org\r\n"
3179 "Connection: keep-alive\r\n\r\n"),
3180 };
3181
3182 MockRead data_reads2[] = {
3183 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3184
3185 MockRead("HTTP/1.1 200 OK\r\n"),
3186 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3187 MockRead("Content-Length: 5\r\n\r\n"),
3188 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593189 };
3190
Ryan Sleevib8d7ea02018-05-07 20:01:013191 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073192 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013193 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543194 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063195 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593197
[email protected]49639fa2011-12-20 23:22:413198 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593199
bnc87dcefc2017-05-25 12:47:583200 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193201 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503202
[email protected]49639fa2011-12-20 23:22:413203 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013204 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593205
3206 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013207 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463208 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403209 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593210 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003211 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3212 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593213 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403214 entries, pos,
mikecirone8b85c432016-09-08 19:11:003215 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3216 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593217
3218 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523219 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013220 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523221 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593222 EXPECT_EQ(407, response->headers->response_code());
3223 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043224 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593225
[email protected]029c83b62013-01-24 05:28:203226 LoadTimingInfo load_timing_info;
3227 // CONNECT requests and responses are handled at the connect job level, so
3228 // the transaction does not yet have a connection.
3229 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3230
[email protected]49639fa2011-12-20 23:22:413231 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593232
[email protected]49639fa2011-12-20 23:22:413233 rv = trans->RestartWithAuth(
3234 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593236
3237 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013238 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593239
3240 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523241 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593242
3243 EXPECT_TRUE(response->headers->IsKeepAlive());
3244 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503245 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593246 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3247
3248 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523249 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503250
[email protected]029c83b62013-01-24 05:28:203251 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3252 TestLoadTimingNotReusedWithPac(load_timing_info,
3253 CONNECT_TIMING_HAS_SSL_TIMES);
3254
[email protected]0b0bf032010-09-21 18:08:503255 trans.reset();
[email protected]102e27c2011-02-23 01:01:313256 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593257}
3258
[email protected]11203f012009-11-12 23:02:313259// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013260// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013261TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233262 // On the second pass, the body read of the auth challenge is synchronous, so
3263 // IsConnectedAndIdle returns false. The socket should still be drained and
3264 // reused. See http://crbug.com/544255.
3265 for (int i = 0; i < 2; ++i) {
3266 HttpRequestInfo request;
3267 request.method = "GET";
3268 request.url = GURL("https://www.example.org/");
3269 // Ensure that proxy authentication is attempted even
3270 // when the no authentication data flag is set.
3271 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103272 request.traffic_annotation =
3273 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013274
mmenked39192ee2015-12-09 00:57:233275 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593276 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493277 ProxyResolutionService::CreateFixed("myproxy:70",
3278 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233279 BoundTestNetLog log;
3280 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013282
bnc691fda62016-08-12 00:43:163283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013284
mmenked39192ee2015-12-09 00:57:233285 // Since we have proxy, should try to establish tunnel.
3286 MockWrite data_writes1[] = {
3287 MockWrite(ASYNC, 0,
3288 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3289 "Host: www.example.org:443\r\n"
3290 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013291
bnc691fda62016-08-12 00:43:163292 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233293 // be issuing -- the final header line contains the credentials.
3294 MockWrite(ASYNC, 3,
3295 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3296 "Host: www.example.org:443\r\n"
3297 "Proxy-Connection: keep-alive\r\n"
3298 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3299 };
ttuttle34f63b52015-03-05 04:33:013300
mmenked39192ee2015-12-09 00:57:233301 // The proxy responds to the connect with a 407, using a persistent
3302 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3303 MockRead data_reads1[] = {
3304 // No credentials.
3305 MockRead(ASYNC, 1,
3306 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3307 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3308 "Proxy-Connection: keep-alive\r\n"
3309 "Content-Length: 10\r\n\r\n"),
3310 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013311
mmenked39192ee2015-12-09 00:57:233312 // Wrong credentials (wrong password).
3313 MockRead(ASYNC, 4,
3314 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3315 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3316 "Proxy-Connection: keep-alive\r\n"
3317 "Content-Length: 10\r\n\r\n"),
3318 // No response body because the test stops reading here.
3319 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3320 };
ttuttle34f63b52015-03-05 04:33:013321
Ryan Sleevib8d7ea02018-05-07 20:01:013322 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233323 data1.set_busy_before_sync_reads(true);
3324 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013325
mmenked39192ee2015-12-09 00:57:233326 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013327
bnc691fda62016-08-12 00:43:163328 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013329 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013330
mmenked39192ee2015-12-09 00:57:233331 TestNetLogEntry::List entries;
3332 log.GetEntries(&entries);
3333 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003334 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3335 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233336 ExpectLogContainsSomewhere(
3337 entries, pos,
mikecirone8b85c432016-09-08 19:11:003338 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3339 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013340
bnc691fda62016-08-12 00:43:163341 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233342 ASSERT_TRUE(response);
3343 ASSERT_TRUE(response->headers);
3344 EXPECT_TRUE(response->headers->IsKeepAlive());
3345 EXPECT_EQ(407, response->headers->response_code());
3346 EXPECT_EQ(10, response->headers->GetContentLength());
3347 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3348 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013349
mmenked39192ee2015-12-09 00:57:233350 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013351
mmenked39192ee2015-12-09 00:57:233352 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163353 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3354 callback2.callback());
robpercival214763f2016-07-01 23:27:013355 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013356
bnc691fda62016-08-12 00:43:163357 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233358 ASSERT_TRUE(response);
3359 ASSERT_TRUE(response->headers);
3360 EXPECT_TRUE(response->headers->IsKeepAlive());
3361 EXPECT_EQ(407, response->headers->response_code());
3362 EXPECT_EQ(10, response->headers->GetContentLength());
3363 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3364 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013365
mmenked39192ee2015-12-09 00:57:233366 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3367 // out of scope.
3368 session->CloseAllConnections();
3369 }
ttuttle34f63b52015-03-05 04:33:013370}
3371
3372// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3373// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013374TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233375 // On the second pass, the body read of the auth challenge is synchronous, so
3376 // IsConnectedAndIdle returns false. The socket should still be drained and
3377 // reused. See http://crbug.com/544255.
3378 for (int i = 0; i < 2; ++i) {
3379 HttpRequestInfo request;
3380 request.method = "GET";
3381 request.url = GURL("https://www.example.org/");
3382 // Ensure that proxy authentication is attempted even
3383 // when the no authentication data flag is set.
3384 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103385 request.traffic_annotation =
3386 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233387
3388 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593389 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493390 ProxyResolutionService::CreateFixed("myproxy:70",
3391 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233392 BoundTestNetLog log;
3393 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233395
bnc691fda62016-08-12 00:43:163396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233397
3398 // Since we have proxy, should try to establish tunnel.
3399 MockWrite data_writes1[] = {
3400 MockWrite(ASYNC, 0,
3401 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3402 "Host: www.example.org:443\r\n"
3403 "Proxy-Connection: keep-alive\r\n\r\n"),
3404
bnc691fda62016-08-12 00:43:163405 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233406 // be issuing -- the final header line contains the credentials.
3407 MockWrite(ASYNC, 3,
3408 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3409 "Host: www.example.org:443\r\n"
3410 "Proxy-Connection: keep-alive\r\n"
3411 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3412 };
3413
3414 // The proxy responds to the connect with a 407, using a persistent
3415 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3416 MockRead data_reads1[] = {
3417 // No credentials.
3418 MockRead(ASYNC, 1,
3419 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3420 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3421 "Content-Length: 10\r\n\r\n"),
3422 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3423
3424 // Wrong credentials (wrong password).
3425 MockRead(ASYNC, 4,
3426 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3427 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3428 "Content-Length: 10\r\n\r\n"),
3429 // No response body because the test stops reading here.
3430 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3431 };
3432
Ryan Sleevib8d7ea02018-05-07 20:01:013433 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233434 data1.set_busy_before_sync_reads(true);
3435 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3436
3437 TestCompletionCallback callback1;
3438
bnc691fda62016-08-12 00:43:163439 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013440 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233441
3442 TestNetLogEntry::List entries;
3443 log.GetEntries(&entries);
3444 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003445 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3446 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233447 ExpectLogContainsSomewhere(
3448 entries, pos,
mikecirone8b85c432016-09-08 19:11:003449 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3450 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233451
bnc691fda62016-08-12 00:43:163452 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233453 ASSERT_TRUE(response);
3454 ASSERT_TRUE(response->headers);
3455 EXPECT_TRUE(response->headers->IsKeepAlive());
3456 EXPECT_EQ(407, response->headers->response_code());
3457 EXPECT_EQ(10, response->headers->GetContentLength());
3458 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3459 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3460
3461 TestCompletionCallback callback2;
3462
3463 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163464 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3465 callback2.callback());
robpercival214763f2016-07-01 23:27:013466 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233467
bnc691fda62016-08-12 00:43:163468 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233469 ASSERT_TRUE(response);
3470 ASSERT_TRUE(response->headers);
3471 EXPECT_TRUE(response->headers->IsKeepAlive());
3472 EXPECT_EQ(407, response->headers->response_code());
3473 EXPECT_EQ(10, response->headers->GetContentLength());
3474 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3475 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3476
3477 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3478 // out of scope.
3479 session->CloseAllConnections();
3480 }
3481}
3482
3483// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3484// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3485// the case the server sends extra data on the original socket, so it can't be
3486// reused.
bncd16676a2016-07-20 16:23:013487TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273488 HttpRequestInfo request;
3489 request.method = "GET";
bncce36dca22015-04-21 22:11:233490 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273491 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293492 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103493 request.traffic_annotation =
3494 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273495
[email protected]2d2697f92009-02-18 21:00:323496 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593497 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493498 ProxyResolutionService::CreateFixedFromPacResult(
3499 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513500 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073501 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093502 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323503
[email protected]2d2697f92009-02-18 21:00:323504 // Since we have proxy, should try to establish tunnel.
3505 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233506 MockWrite(ASYNC, 0,
3507 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173508 "Host: www.example.org:443\r\n"
3509 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233510 };
[email protected]2d2697f92009-02-18 21:00:323511
mmenked39192ee2015-12-09 00:57:233512 // The proxy responds to the connect with a 407, using a persistent, but sends
3513 // extra data, so the socket cannot be reused.
3514 MockRead data_reads1[] = {
3515 // No credentials.
3516 MockRead(ASYNC, 1,
3517 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3518 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3519 "Content-Length: 10\r\n\r\n"),
3520 MockRead(SYNCHRONOUS, 2, "0123456789"),
3521 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3522 };
3523
3524 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233525 // After calling trans->RestartWithAuth(), this is the request we should
3526 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233527 MockWrite(ASYNC, 0,
3528 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173529 "Host: www.example.org:443\r\n"
3530 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233531 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3532
3533 MockWrite(ASYNC, 2,
3534 "GET / HTTP/1.1\r\n"
3535 "Host: www.example.org\r\n"
3536 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323537 };
3538
mmenked39192ee2015-12-09 00:57:233539 MockRead data_reads2[] = {
3540 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323541
mmenked39192ee2015-12-09 00:57:233542 MockRead(ASYNC, 3,
3543 "HTTP/1.1 200 OK\r\n"
3544 "Content-Type: text/html; charset=iso-8859-1\r\n"
3545 "Content-Length: 5\r\n\r\n"),
3546 // No response body because the test stops reading here.
3547 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323548 };
3549
Ryan Sleevib8d7ea02018-05-07 20:01:013550 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233551 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073552 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013553 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3555 SSLSocketDataProvider ssl(ASYNC, OK);
3556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323557
[email protected]49639fa2011-12-20 23:22:413558 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323559
bnc87dcefc2017-05-25 12:47:583560 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193561 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323562
mmenked39192ee2015-12-09 00:57:233563 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013564 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233565
mmenke43758e62015-05-04 21:09:463566 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403567 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393568 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003569 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3570 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393571 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403572 entries, pos,
mikecirone8b85c432016-09-08 19:11:003573 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3574 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323575
[email protected]1c773ea12009-04-28 19:58:423576 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243577 ASSERT_TRUE(response);
3578 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323579 EXPECT_TRUE(response->headers->IsKeepAlive());
3580 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423581 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043582 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323583
mmenked39192ee2015-12-09 00:57:233584 LoadTimingInfo load_timing_info;
3585 // CONNECT requests and responses are handled at the connect job level, so
3586 // the transaction does not yet have a connection.
3587 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3588
[email protected]49639fa2011-12-20 23:22:413589 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323590
mmenked39192ee2015-12-09 00:57:233591 rv =
3592 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013593 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323594
[email protected]2d2697f92009-02-18 21:00:323595 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233596 EXPECT_EQ(200, response->headers->response_code());
3597 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423598 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133599
mmenked39192ee2015-12-09 00:57:233600 // The password prompt info should not be set.
3601 EXPECT_FALSE(response->auth_challenge);
3602
3603 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3604 TestLoadTimingNotReusedWithPac(load_timing_info,
3605 CONNECT_TIMING_HAS_SSL_TIMES);
3606
3607 trans.reset();
[email protected]102e27c2011-02-23 01:01:313608 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323609}
3610
mmenkee71e15332015-10-07 16:39:543611// Test the case a proxy closes a socket while the challenge body is being
3612// drained.
bncd16676a2016-07-20 16:23:013613TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543614 HttpRequestInfo request;
3615 request.method = "GET";
3616 request.url = GURL("https://www.example.org/");
3617 // Ensure that proxy authentication is attempted even
3618 // when the no authentication data flag is set.
3619 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103620 request.traffic_annotation =
3621 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543622
3623 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493624 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3625 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093626 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543627
bnc691fda62016-08-12 00:43:163628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543629
3630 // Since we have proxy, should try to establish tunnel.
3631 MockWrite data_writes1[] = {
3632 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173633 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543634 "Proxy-Connection: keep-alive\r\n\r\n"),
3635 };
3636
3637 // The proxy responds to the connect with a 407, using a persistent
3638 // connection.
3639 MockRead data_reads1[] = {
3640 // No credentials.
3641 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3642 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3643 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3644 // Server hands up in the middle of the body.
3645 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3646 };
3647
3648 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163649 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543650 // be issuing -- the final header line contains the credentials.
3651 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173652 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543653 "Proxy-Connection: keep-alive\r\n"
3654 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3655
3656 MockWrite("GET / HTTP/1.1\r\n"
3657 "Host: www.example.org\r\n"
3658 "Connection: keep-alive\r\n\r\n"),
3659 };
3660
3661 MockRead data_reads2[] = {
3662 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3663
3664 MockRead("HTTP/1.1 200 OK\r\n"),
3665 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3666 MockRead("Content-Length: 5\r\n\r\n"),
3667 MockRead(SYNCHRONOUS, "hello"),
3668 };
3669
Ryan Sleevib8d7ea02018-05-07 20:01:013670 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543671 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013672 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543673 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3674 SSLSocketDataProvider ssl(ASYNC, OK);
3675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3676
3677 TestCompletionCallback callback;
3678
tfarina42834112016-09-22 13:38:203679 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013680 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543681
bnc691fda62016-08-12 00:43:163682 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543683 ASSERT_TRUE(response);
3684 ASSERT_TRUE(response->headers);
3685 EXPECT_TRUE(response->headers->IsKeepAlive());
3686 EXPECT_EQ(407, response->headers->response_code());
3687 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3688
bnc691fda62016-08-12 00:43:163689 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013690 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543691
bnc691fda62016-08-12 00:43:163692 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543693 ASSERT_TRUE(response);
3694 ASSERT_TRUE(response->headers);
3695 EXPECT_TRUE(response->headers->IsKeepAlive());
3696 EXPECT_EQ(200, response->headers->response_code());
3697 std::string body;
bnc691fda62016-08-12 00:43:163698 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543699 EXPECT_EQ("hello", body);
3700}
3701
[email protected]a8e9b162009-03-12 00:06:443702// Test that we don't read the response body when we fail to establish a tunnel,
3703// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013704TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273705 HttpRequestInfo request;
3706 request.method = "GET";
bncce36dca22015-04-21 22:11:233707 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103708 request.traffic_annotation =
3709 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273710
[email protected]a8e9b162009-03-12 00:06:443711 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493712 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3713 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443714
danakj1fd259a02016-04-16 03:17:093715 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443716
bnc691fda62016-08-12 00:43:163717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443718
[email protected]a8e9b162009-03-12 00:06:443719 // Since we have proxy, should try to establish tunnel.
3720 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173721 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3722 "Host: www.example.org:443\r\n"
3723 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443724 };
3725
3726 // The proxy responds to the connect with a 407.
3727 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243728 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3729 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3730 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233731 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243732 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443733 };
3734
Ryan Sleevib8d7ea02018-05-07 20:01:013735 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073736 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443737
[email protected]49639fa2011-12-20 23:22:413738 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443739
tfarina42834112016-09-22 13:38:203740 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443742
3743 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013744 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443745
bnc691fda62016-08-12 00:43:163746 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243747 ASSERT_TRUE(response);
3748 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443749 EXPECT_TRUE(response->headers->IsKeepAlive());
3750 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423751 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443752
3753 std::string response_data;
bnc691fda62016-08-12 00:43:163754 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013755 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183756
3757 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313758 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443759}
3760
ttuttle7933c112015-01-06 00:55:243761// Test that we don't pass extraneous headers from the proxy's response to the
3762// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013763TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243764 HttpRequestInfo request;
3765 request.method = "GET";
bncce36dca22015-04-21 22:11:233766 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103767 request.traffic_annotation =
3768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243769
3770 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493771 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3772 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243773
danakj1fd259a02016-04-16 03:17:093774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243775
bnc691fda62016-08-12 00:43:163776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243777
3778 // Since we have proxy, should try to establish tunnel.
3779 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173780 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3781 "Host: www.example.org:443\r\n"
3782 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243783 };
3784
3785 // The proxy responds to the connect with a 407.
3786 MockRead data_reads[] = {
3787 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3788 MockRead("X-Foo: bar\r\n"),
3789 MockRead("Set-Cookie: foo=bar\r\n"),
3790 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3791 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233792 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243793 };
3794
Ryan Sleevib8d7ea02018-05-07 20:01:013795 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:243796 session_deps_.socket_factory->AddSocketDataProvider(&data);
3797
3798 TestCompletionCallback callback;
3799
tfarina42834112016-09-22 13:38:203800 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243802
3803 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013804 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243805
bnc691fda62016-08-12 00:43:163806 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243807 ASSERT_TRUE(response);
3808 ASSERT_TRUE(response->headers);
3809 EXPECT_TRUE(response->headers->IsKeepAlive());
3810 EXPECT_EQ(407, response->headers->response_code());
3811 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3812 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3813 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3814
3815 std::string response_data;
bnc691fda62016-08-12 00:43:163816 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013817 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243818
3819 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3820 session->CloseAllConnections();
3821}
3822
[email protected]8fdbcd22010-05-05 02:54:523823// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3824// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013825TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523826 HttpRequestInfo request;
3827 request.method = "GET";
bncce36dca22015-04-21 22:11:233828 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103829 request.traffic_annotation =
3830 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523831
[email protected]cb9bf6ca2011-01-28 13:15:273832 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273835
[email protected]8fdbcd22010-05-05 02:54:523836 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233837 MockWrite(
3838 "GET / HTTP/1.1\r\n"
3839 "Host: www.example.org\r\n"
3840 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523841 };
3842
3843 MockRead data_reads1[] = {
3844 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3845 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3846 // Large content-length -- won't matter, as connection will be reset.
3847 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063848 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523849 };
3850
Ryan Sleevib8d7ea02018-05-07 20:01:013851 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073852 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523853
[email protected]49639fa2011-12-20 23:22:413854 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523855
tfarina42834112016-09-22 13:38:203856 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523858
3859 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013860 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523861}
3862
[email protected]7a67a8152010-11-05 18:31:103863// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3864// through a non-authenticating proxy. The request should fail with
3865// ERR_UNEXPECTED_PROXY_AUTH.
3866// Note that it is impossible to detect if an HTTP server returns a 407 through
3867// a non-authenticating proxy - there is nothing to indicate whether the
3868// response came from the proxy or the server, so it is treated as if the proxy
3869// issued the challenge.
bncd16676a2016-07-20 16:23:013870TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273871 HttpRequestInfo request;
3872 request.method = "GET";
bncce36dca22015-04-21 22:11:233873 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103874 request.traffic_annotation =
3875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273876
Ramin Halavatica8d5252018-03-12 05:33:493877 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3878 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513879 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073880 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103882
[email protected]7a67a8152010-11-05 18:31:103883 // Since we have proxy, should try to establish tunnel.
3884 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173885 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3886 "Host: www.example.org:443\r\n"
3887 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103888
rsleevidb16bb02015-11-12 23:47:173889 MockWrite("GET / HTTP/1.1\r\n"
3890 "Host: www.example.org\r\n"
3891 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103892 };
3893
3894 MockRead data_reads1[] = {
3895 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3896
3897 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3898 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3899 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063900 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103901 };
3902
Ryan Sleevib8d7ea02018-05-07 20:01:013903 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073904 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063905 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073906 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103907
[email protected]49639fa2011-12-20 23:22:413908 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103909
bnc691fda62016-08-12 00:43:163910 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103911
bnc691fda62016-08-12 00:43:163912 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103914
3915 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013916 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463917 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403918 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103919 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003920 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3921 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103922 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403923 entries, pos,
mikecirone8b85c432016-09-08 19:11:003924 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3925 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103926}
[email protected]2df19bb2010-08-25 20:13:463927
mmenke2a1781d2015-10-07 19:25:333928// Test a proxy auth scheme that allows default credentials and a proxy server
3929// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013930TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333931 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3932 HttpRequestInfo request;
3933 request.method = "GET";
3934 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103935 request.traffic_annotation =
3936 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333937
3938 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593939 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493940 ProxyResolutionService::CreateFixedFromPacResult(
3941 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333942
Jeremy Roman0579ed62017-08-29 15:56:193943 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333944 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193945 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333946 mock_handler->set_allows_default_credentials(true);
3947 auth_handler_factory->AddMockHandler(mock_handler.release(),
3948 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483949 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333950
3951 // Add NetLog just so can verify load timing information gets a NetLog ID.
3952 NetLog net_log;
3953 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093954 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333955
3956 // Since we have proxy, should try to establish tunnel.
3957 MockWrite data_writes1[] = {
3958 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173959 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333960 "Proxy-Connection: keep-alive\r\n\r\n"),
3961 };
3962
3963 // The proxy responds to the connect with a 407, using a non-persistent
3964 // connection.
3965 MockRead data_reads1[] = {
3966 // No credentials.
3967 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3968 MockRead("Proxy-Authenticate: Mock\r\n"),
3969 MockRead("Proxy-Connection: close\r\n\r\n"),
3970 };
3971
3972 // Since the first connection couldn't be reused, need to establish another
3973 // once given credentials.
3974 MockWrite data_writes2[] = {
3975 // After calling trans->RestartWithAuth(), this is the request we should
3976 // be issuing -- the final header line contains the credentials.
3977 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173978 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333979 "Proxy-Connection: keep-alive\r\n"
3980 "Proxy-Authorization: auth_token\r\n\r\n"),
3981
3982 MockWrite("GET / HTTP/1.1\r\n"
3983 "Host: www.example.org\r\n"
3984 "Connection: keep-alive\r\n\r\n"),
3985 };
3986
3987 MockRead data_reads2[] = {
3988 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3989
3990 MockRead("HTTP/1.1 200 OK\r\n"),
3991 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3992 MockRead("Content-Length: 5\r\n\r\n"),
3993 MockRead(SYNCHRONOUS, "hello"),
3994 };
3995
Ryan Sleevib8d7ea02018-05-07 20:01:013996 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:333997 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013998 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:333999 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4000 SSLSocketDataProvider ssl(ASYNC, OK);
4001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4002
bnc87dcefc2017-05-25 12:47:584003 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194004 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334005
4006 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204007 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014008 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334009
4010 const HttpResponseInfo* response = trans->GetResponseInfo();
4011 ASSERT_TRUE(response);
4012 ASSERT_TRUE(response->headers);
4013 EXPECT_FALSE(response->headers->IsKeepAlive());
4014 EXPECT_EQ(407, response->headers->response_code());
4015 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4016 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524017 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334018
4019 LoadTimingInfo load_timing_info;
4020 // CONNECT requests and responses are handled at the connect job level, so
4021 // the transaction does not yet have a connection.
4022 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4023
4024 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014025 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334026 response = trans->GetResponseInfo();
4027 ASSERT_TRUE(response);
4028 ASSERT_TRUE(response->headers);
4029 EXPECT_TRUE(response->headers->IsKeepAlive());
4030 EXPECT_EQ(200, response->headers->response_code());
4031 EXPECT_EQ(5, response->headers->GetContentLength());
4032 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4033
4034 // The password prompt info should not be set.
4035 EXPECT_FALSE(response->auth_challenge);
4036
4037 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4038 TestLoadTimingNotReusedWithPac(load_timing_info,
4039 CONNECT_TIMING_HAS_SSL_TIMES);
4040
4041 trans.reset();
4042 session->CloseAllConnections();
4043}
4044
4045// Test a proxy auth scheme that allows default credentials and a proxy server
4046// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014047TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334048 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4049 HttpRequestInfo request;
4050 request.method = "GET";
4051 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104052 request.traffic_annotation =
4053 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334054
4055 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594056 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494057 ProxyResolutionService::CreateFixedFromPacResult(
4058 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334059
Jeremy Roman0579ed62017-08-29 15:56:194060 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334061 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194062 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334063 mock_handler->set_allows_default_credentials(true);
4064 auth_handler_factory->AddMockHandler(mock_handler.release(),
4065 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484066 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334067
4068 // Add NetLog just so can verify load timing information gets a NetLog ID.
4069 NetLog net_log;
4070 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094071 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334072
4073 // Should try to establish tunnel.
4074 MockWrite data_writes1[] = {
4075 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174076 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334077 "Proxy-Connection: keep-alive\r\n\r\n"),
4078
4079 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174080 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334081 "Proxy-Connection: keep-alive\r\n"
4082 "Proxy-Authorization: auth_token\r\n\r\n"),
4083 };
4084
4085 // The proxy responds to the connect with a 407, using a non-persistent
4086 // connection.
4087 MockRead data_reads1[] = {
4088 // No credentials.
4089 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4090 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4091 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4092 };
4093
4094 // Since the first connection was closed, need to establish another once given
4095 // credentials.
4096 MockWrite data_writes2[] = {
4097 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174098 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334099 "Proxy-Connection: keep-alive\r\n"
4100 "Proxy-Authorization: auth_token\r\n\r\n"),
4101
4102 MockWrite("GET / HTTP/1.1\r\n"
4103 "Host: www.example.org\r\n"
4104 "Connection: keep-alive\r\n\r\n"),
4105 };
4106
4107 MockRead data_reads2[] = {
4108 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4109
4110 MockRead("HTTP/1.1 200 OK\r\n"),
4111 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4112 MockRead("Content-Length: 5\r\n\r\n"),
4113 MockRead(SYNCHRONOUS, "hello"),
4114 };
4115
Ryan Sleevib8d7ea02018-05-07 20:01:014116 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334117 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014118 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334119 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4120 SSLSocketDataProvider ssl(ASYNC, OK);
4121 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4122
bnc87dcefc2017-05-25 12:47:584123 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194124 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334125
4126 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204127 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014128 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334129
4130 const HttpResponseInfo* response = trans->GetResponseInfo();
4131 ASSERT_TRUE(response);
4132 ASSERT_TRUE(response->headers);
4133 EXPECT_TRUE(response->headers->IsKeepAlive());
4134 EXPECT_EQ(407, response->headers->response_code());
4135 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4136 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4137 EXPECT_FALSE(response->auth_challenge);
4138
4139 LoadTimingInfo load_timing_info;
4140 // CONNECT requests and responses are handled at the connect job level, so
4141 // the transaction does not yet have a connection.
4142 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4143
4144 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014145 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334146
4147 response = trans->GetResponseInfo();
4148 ASSERT_TRUE(response);
4149 ASSERT_TRUE(response->headers);
4150 EXPECT_TRUE(response->headers->IsKeepAlive());
4151 EXPECT_EQ(200, response->headers->response_code());
4152 EXPECT_EQ(5, response->headers->GetContentLength());
4153 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4154
4155 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524156 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334157
4158 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4159 TestLoadTimingNotReusedWithPac(load_timing_info,
4160 CONNECT_TIMING_HAS_SSL_TIMES);
4161
4162 trans.reset();
4163 session->CloseAllConnections();
4164}
4165
4166// Test a proxy auth scheme that allows default credentials and a proxy server
4167// that hangs up when credentials are initially sent, and hangs up again when
4168// they are retried.
bncd16676a2016-07-20 16:23:014169TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334170 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4171 HttpRequestInfo request;
4172 request.method = "GET";
4173 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104174 request.traffic_annotation =
4175 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334176
4177 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594178 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494179 ProxyResolutionService::CreateFixedFromPacResult(
4180 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334181
Jeremy Roman0579ed62017-08-29 15:56:194182 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334183 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194184 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334185 mock_handler->set_allows_default_credentials(true);
4186 auth_handler_factory->AddMockHandler(mock_handler.release(),
4187 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484188 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334189
4190 // Add NetLog just so can verify load timing information gets a NetLog ID.
4191 NetLog net_log;
4192 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094193 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334194
4195 // Should try to establish tunnel.
4196 MockWrite data_writes1[] = {
4197 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174198 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334199 "Proxy-Connection: keep-alive\r\n\r\n"),
4200
4201 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174202 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334203 "Proxy-Connection: keep-alive\r\n"
4204 "Proxy-Authorization: auth_token\r\n\r\n"),
4205 };
4206
4207 // The proxy responds to the connect with a 407, and then hangs up after the
4208 // second request is sent.
4209 MockRead data_reads1[] = {
4210 // No credentials.
4211 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4212 MockRead("Content-Length: 0\r\n"),
4213 MockRead("Proxy-Connection: keep-alive\r\n"),
4214 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4215 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4216 };
4217
4218 // HttpNetworkTransaction sees a reused connection that was closed with
4219 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4220 // request.
4221 MockWrite data_writes2[] = {
4222 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174223 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334224 "Proxy-Connection: keep-alive\r\n\r\n"),
4225 };
4226
4227 // The proxy, having had more than enough of us, just hangs up.
4228 MockRead data_reads2[] = {
4229 // No credentials.
4230 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4231 };
4232
Ryan Sleevib8d7ea02018-05-07 20:01:014233 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334234 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014235 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334236 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4237
bnc87dcefc2017-05-25 12:47:584238 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194239 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334240
4241 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204242 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014243 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334244
4245 const HttpResponseInfo* response = trans->GetResponseInfo();
4246 ASSERT_TRUE(response);
4247 ASSERT_TRUE(response->headers);
4248 EXPECT_TRUE(response->headers->IsKeepAlive());
4249 EXPECT_EQ(407, response->headers->response_code());
4250 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4251 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4252 EXPECT_FALSE(response->auth_challenge);
4253
4254 LoadTimingInfo load_timing_info;
4255 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4256
4257 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014258 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334259
4260 trans.reset();
4261 session->CloseAllConnections();
4262}
4263
4264// Test a proxy auth scheme that allows default credentials and a proxy server
4265// that hangs up when credentials are initially sent, and sends a challenge
4266// again they are retried.
bncd16676a2016-07-20 16:23:014267TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334268 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4269 HttpRequestInfo request;
4270 request.method = "GET";
4271 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104272 request.traffic_annotation =
4273 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334274
4275 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594276 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494277 ProxyResolutionService::CreateFixedFromPacResult(
4278 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334279
Jeremy Roman0579ed62017-08-29 15:56:194280 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334281 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194282 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334283 mock_handler->set_allows_default_credentials(true);
4284 auth_handler_factory->AddMockHandler(mock_handler.release(),
4285 HttpAuth::AUTH_PROXY);
4286 // Add another handler for the second challenge. It supports default
4287 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194288 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);
dchengc7eeda422015-12-26 03:56:484292 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334293
4294 // Add NetLog just so can verify load timing information gets a NetLog ID.
4295 NetLog net_log;
4296 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094297 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334298
4299 // Should try to establish tunnel.
4300 MockWrite data_writes1[] = {
4301 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174302 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334303 "Proxy-Connection: keep-alive\r\n\r\n"),
4304 };
4305
4306 // The proxy responds to the connect with a 407, using a non-persistent
4307 // connection.
4308 MockRead data_reads1[] = {
4309 // No credentials.
4310 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4311 MockRead("Proxy-Authenticate: Mock\r\n"),
4312 MockRead("Proxy-Connection: close\r\n\r\n"),
4313 };
4314
4315 // Since the first connection was closed, need to establish another once given
4316 // credentials.
4317 MockWrite data_writes2[] = {
4318 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174319 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334320 "Proxy-Connection: keep-alive\r\n"
4321 "Proxy-Authorization: auth_token\r\n\r\n"),
4322 };
4323
4324 MockRead data_reads2[] = {
4325 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4326 MockRead("Proxy-Authenticate: Mock\r\n"),
4327 MockRead("Proxy-Connection: close\r\n\r\n"),
4328 };
4329
Ryan Sleevib8d7ea02018-05-07 20:01:014330 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334331 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014332 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334333 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4334 SSLSocketDataProvider ssl(ASYNC, OK);
4335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4336
bnc87dcefc2017-05-25 12:47:584337 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194338 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334339
4340 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204341 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014342 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334343
4344 const HttpResponseInfo* response = trans->GetResponseInfo();
4345 ASSERT_TRUE(response);
4346 ASSERT_TRUE(response->headers);
4347 EXPECT_EQ(407, response->headers->response_code());
4348 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4349 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4350 EXPECT_FALSE(response->auth_challenge);
4351
4352 LoadTimingInfo load_timing_info;
4353 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4354
4355 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014356 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334357 response = trans->GetResponseInfo();
4358 ASSERT_TRUE(response);
4359 ASSERT_TRUE(response->headers);
4360 EXPECT_EQ(407, response->headers->response_code());
4361 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4362 EXPECT_TRUE(response->auth_challenge);
4363
4364 trans.reset();
4365 session->CloseAllConnections();
4366}
4367
asankae2257db2016-10-11 22:03:164368// A more nuanced test than GenerateAuthToken test which asserts that
4369// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4370// unnecessarily invalidated, and that if the server co-operates, the
4371// authentication handshake can continue with the same scheme but with a
4372// different identity.
4373TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4374 HttpRequestInfo request;
4375 request.method = "GET";
4376 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104377 request.traffic_annotation =
4378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164379
Jeremy Roman0579ed62017-08-29 15:56:194380 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164381 auth_handler_factory->set_do_init_from_challenge(true);
4382
4383 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194384 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164385 mock_handler->set_allows_default_credentials(true);
4386 mock_handler->set_allows_explicit_credentials(true);
4387 mock_handler->set_connection_based(true);
4388 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4389 auth_handler_factory->AddMockHandler(mock_handler.release(),
4390 HttpAuth::AUTH_SERVER);
4391
4392 // Add another handler for the second challenge. It supports default
4393 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194394 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164395 mock_handler->set_allows_default_credentials(true);
4396 mock_handler->set_allows_explicit_credentials(true);
4397 mock_handler->set_connection_based(true);
4398 auth_handler_factory->AddMockHandler(mock_handler.release(),
4399 HttpAuth::AUTH_SERVER);
4400 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4401
4402 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4403
4404 MockWrite data_writes1[] = {
4405 MockWrite("GET / HTTP/1.1\r\n"
4406 "Host: www.example.org\r\n"
4407 "Connection: keep-alive\r\n\r\n"),
4408 };
4409
4410 MockRead data_reads1[] = {
4411 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4412 "WWW-Authenticate: Mock\r\n"
4413 "Connection: keep-alive\r\n\r\n"),
4414 };
4415
4416 // Identical to data_writes1[]. The AuthHandler encounters a
4417 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4418 // transaction procceds without an authorization header.
4419 MockWrite data_writes2[] = {
4420 MockWrite("GET / HTTP/1.1\r\n"
4421 "Host: www.example.org\r\n"
4422 "Connection: keep-alive\r\n\r\n"),
4423 };
4424
4425 MockRead data_reads2[] = {
4426 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4427 "WWW-Authenticate: Mock\r\n"
4428 "Connection: keep-alive\r\n\r\n"),
4429 };
4430
4431 MockWrite data_writes3[] = {
4432 MockWrite("GET / HTTP/1.1\r\n"
4433 "Host: www.example.org\r\n"
4434 "Connection: keep-alive\r\n"
4435 "Authorization: auth_token\r\n\r\n"),
4436 };
4437
4438 MockRead data_reads3[] = {
4439 MockRead("HTTP/1.1 200 OK\r\n"
4440 "Content-Length: 5\r\n"
4441 "Content-Type: text/plain\r\n"
4442 "Connection: keep-alive\r\n\r\n"
4443 "Hello"),
4444 };
4445
Ryan Sleevib8d7ea02018-05-07 20:01:014446 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164447 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4448
Ryan Sleevib8d7ea02018-05-07 20:01:014449 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164450 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4451
Ryan Sleevib8d7ea02018-05-07 20:01:014452 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164453 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4454
bnc87dcefc2017-05-25 12:47:584455 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194456 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164457
4458 TestCompletionCallback callback;
4459 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4460 EXPECT_THAT(callback.GetResult(rv), IsOk());
4461
4462 const HttpResponseInfo* response = trans->GetResponseInfo();
4463 ASSERT_TRUE(response);
4464 ASSERT_TRUE(response->headers);
4465 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4466
4467 // The following three tests assert that an authentication challenge was
4468 // received and that the stack is ready to respond to the challenge using
4469 // ambient credentials.
4470 EXPECT_EQ(401, response->headers->response_code());
4471 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4472 EXPECT_FALSE(response->auth_challenge);
4473
4474 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4475 EXPECT_THAT(callback.GetResult(rv), IsOk());
4476 response = trans->GetResponseInfo();
4477 ASSERT_TRUE(response);
4478 ASSERT_TRUE(response->headers);
4479
4480 // The following three tests assert that an authentication challenge was
4481 // received and that the stack needs explicit credentials before it is ready
4482 // to respond to the challenge.
4483 EXPECT_EQ(401, response->headers->response_code());
4484 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4485 EXPECT_TRUE(response->auth_challenge);
4486
4487 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4488 EXPECT_THAT(callback.GetResult(rv), IsOk());
4489 response = trans->GetResponseInfo();
4490 ASSERT_TRUE(response);
4491 ASSERT_TRUE(response->headers);
4492 EXPECT_EQ(200, response->headers->response_code());
4493
4494 trans.reset();
4495 session->CloseAllConnections();
4496}
4497
Matt Menked1eb6d42018-01-17 04:54:064498// Proxy resolver that returns a proxy with the same host and port for different
4499// schemes, based on the path of the URL being requests.
4500class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4501 public:
4502 SameProxyWithDifferentSchemesProxyResolver() {}
4503 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4504
4505 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4506
4507 static HostPortPair ProxyHostPortPair() {
4508 return HostPortPair::FromString(ProxyHostPortPairAsString());
4509 }
4510
4511 // ProxyResolver implementation.
4512 int GetProxyForURL(const GURL& url,
4513 ProxyInfo* results,
4514 const CompletionCallback& callback,
4515 std::unique_ptr<Request>* request,
4516 const NetLogWithSource& /*net_log*/) override {
4517 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574518 results->set_traffic_annotation(
4519 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064520 if (url.path() == "/socks4") {
4521 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4522 return OK;
4523 }
4524 if (url.path() == "/socks5") {
4525 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4526 return OK;
4527 }
4528 if (url.path() == "/http") {
4529 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4530 return OK;
4531 }
4532 if (url.path() == "/https") {
4533 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4534 return OK;
4535 }
4536 NOTREACHED();
4537 return ERR_NOT_IMPLEMENTED;
4538 }
4539
4540 private:
4541 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4542};
4543
4544class SameProxyWithDifferentSchemesProxyResolverFactory
4545 : public ProxyResolverFactory {
4546 public:
4547 SameProxyWithDifferentSchemesProxyResolverFactory()
4548 : ProxyResolverFactory(false) {}
4549
Lily Houghton99597862018-03-07 16:40:424550 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4551 std::unique_ptr<ProxyResolver>* resolver,
4552 const CompletionCallback& callback,
4553 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064554 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4555 return OK;
4556 }
4557
4558 private:
4559 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4560};
4561
4562// Check that when different proxy schemes are all applied to a proxy at the
4563// same address, the sonnections are not grouped together. i.e., a request to
4564// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4565// request to foo.com using proxy.com as an HTTP proxy.
4566TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494567 session_deps_.proxy_resolution_service =
4568 std::make_unique<ProxyResolutionService>(
4569 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4570 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4571 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4572 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064573
4574 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4575
4576 MockWrite socks_writes[] = {
4577 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4578 kSOCKS4OkRequestLocalHostPort80Length),
4579 MockWrite(SYNCHRONOUS,
4580 "GET /socks4 HTTP/1.1\r\n"
4581 "Host: test\r\n"
4582 "Connection: keep-alive\r\n\r\n"),
4583 };
4584 MockRead socks_reads[] = {
4585 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4586 MockRead("HTTP/1.0 200 OK\r\n"
4587 "Connection: keep-alive\r\n"
4588 "Content-Length: 15\r\n\r\n"
4589 "SOCKS4 Response"),
4590 };
Ryan Sleevib8d7ea02018-05-07 20:01:014591 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064592 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4593
4594 const char kSOCKS5Request[] = {
4595 0x05, // Version
4596 0x01, // Command (CONNECT)
4597 0x00, // Reserved
4598 0x03, // Address type (DOMAINNAME)
4599 0x04, // Length of domain (4)
4600 't', 'e', 's', 't', // Domain string
4601 0x00, 0x50, // 16-bit port (80)
4602 };
4603 MockWrite socks5_writes[] = {
4604 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4605 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4606 MockWrite(SYNCHRONOUS,
4607 "GET /socks5 HTTP/1.1\r\n"
4608 "Host: test\r\n"
4609 "Connection: keep-alive\r\n\r\n"),
4610 };
4611 MockRead socks5_reads[] = {
4612 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4613 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4614 MockRead("HTTP/1.0 200 OK\r\n"
4615 "Connection: keep-alive\r\n"
4616 "Content-Length: 15\r\n\r\n"
4617 "SOCKS5 Response"),
4618 };
Ryan Sleevib8d7ea02018-05-07 20:01:014619 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:064620 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4621
4622 MockWrite http_writes[] = {
4623 MockWrite(SYNCHRONOUS,
4624 "GET http://test/http HTTP/1.1\r\n"
4625 "Host: test\r\n"
4626 "Proxy-Connection: keep-alive\r\n\r\n"),
4627 };
4628 MockRead http_reads[] = {
4629 MockRead("HTTP/1.1 200 OK\r\n"
4630 "Proxy-Connection: keep-alive\r\n"
4631 "Content-Length: 13\r\n\r\n"
4632 "HTTP Response"),
4633 };
Ryan Sleevib8d7ea02018-05-07 20:01:014634 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:064635 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4636
4637 MockWrite https_writes[] = {
4638 MockWrite(SYNCHRONOUS,
4639 "GET http://test/https HTTP/1.1\r\n"
4640 "Host: test\r\n"
4641 "Proxy-Connection: keep-alive\r\n\r\n"),
4642 };
4643 MockRead https_reads[] = {
4644 MockRead("HTTP/1.1 200 OK\r\n"
4645 "Proxy-Connection: keep-alive\r\n"
4646 "Content-Length: 14\r\n\r\n"
4647 "HTTPS Response"),
4648 };
Ryan Sleevib8d7ea02018-05-07 20:01:014649 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:064650 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4651 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4652 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4653
4654 struct TestCase {
4655 GURL url;
4656 std::string expected_response;
4657 // How many idle sockets there should be in the SOCKS proxy socket pool
4658 // after the test.
4659 int expected_idle_socks_sockets;
4660 // How many idle sockets there should be in the HTTP proxy socket pool after
4661 // the test.
4662 int expected_idle_http_sockets;
4663 } const kTestCases[] = {
4664 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4665 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4666 {GURL("http://test/http"), "HTTP Response", 2, 1},
4667 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4668 };
4669
4670 for (const auto& test_case : kTestCases) {
4671 HttpRequestInfo request;
4672 request.method = "GET";
4673 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:104674 request.traffic_annotation =
4675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064676 std::unique_ptr<HttpNetworkTransaction> trans =
4677 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4678 session.get());
4679 TestCompletionCallback callback;
4680 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4681 EXPECT_THAT(callback.GetResult(rv), IsOk());
4682
4683 const HttpResponseInfo* response = trans->GetResponseInfo();
4684 ASSERT_TRUE(response);
4685 ASSERT_TRUE(response->headers);
4686 EXPECT_EQ(200, response->headers->response_code());
4687 std::string response_data;
4688 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4689 EXPECT_EQ(test_case.expected_response, response_data);
4690
4691 // Return the socket to the socket pool, so can make sure it's not used for
4692 // the next requests.
4693 trans.reset();
4694 base::RunLoop().RunUntilIdle();
4695
4696 // Check the number of idle sockets in the pool, to make sure that used
4697 // sockets are indeed being returned to the socket pool. If each request
4698 // doesn't return an idle socket to the pool, the test would incorrectly
4699 // pass.
4700 EXPECT_EQ(
4701 test_case.expected_idle_socks_sockets,
4702 session
4703 ->GetSocketPoolForSOCKSProxy(
4704 HttpNetworkSession::NORMAL_SOCKET_POOL,
4705 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4706 ->IdleSocketCount());
4707 EXPECT_EQ(
4708 test_case.expected_idle_http_sockets,
4709 session
4710 ->GetSocketPoolForHTTPProxy(
4711 HttpNetworkSession::NORMAL_SOCKET_POOL,
4712 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4713 ->IdleSocketCount());
4714 }
4715}
4716
[email protected]029c83b62013-01-24 05:28:204717// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014718TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204719 HttpRequestInfo request1;
4720 request1.method = "GET";
bncce36dca22015-04-21 22:11:234721 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104722 request1.traffic_annotation =
4723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204724
4725 HttpRequestInfo request2;
4726 request2.method = "GET";
bncce36dca22015-04-21 22:11:234727 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104728 request2.traffic_annotation =
4729 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204730
4731 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494732 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4733 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514734 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074735 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204737
4738 // Since we have proxy, should try to establish tunnel.
4739 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174740 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4741 "Host: www.example.org:443\r\n"
4742 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204743
rsleevidb16bb02015-11-12 23:47:174744 MockWrite("GET /1 HTTP/1.1\r\n"
4745 "Host: www.example.org\r\n"
4746 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204747
rsleevidb16bb02015-11-12 23:47:174748 MockWrite("GET /2 HTTP/1.1\r\n"
4749 "Host: www.example.org\r\n"
4750 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204751 };
4752
4753 // The proxy responds to the connect with a 407, using a persistent
4754 // connection.
4755 MockRead data_reads1[] = {
4756 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4757
4758 MockRead("HTTP/1.1 200 OK\r\n"),
4759 MockRead("Content-Length: 1\r\n\r\n"),
4760 MockRead(SYNCHRONOUS, "1"),
4761
4762 MockRead("HTTP/1.1 200 OK\r\n"),
4763 MockRead("Content-Length: 2\r\n\r\n"),
4764 MockRead(SYNCHRONOUS, "22"),
4765 };
4766
Ryan Sleevib8d7ea02018-05-07 20:01:014767 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074768 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204769 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204771
4772 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584773 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194774 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204775
4776 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204778
4779 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014780 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204781
4782 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524783 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474784 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524785 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204786 EXPECT_EQ(1, response1->headers->GetContentLength());
4787
4788 LoadTimingInfo load_timing_info1;
4789 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4790 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4791
4792 trans1.reset();
4793
4794 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584795 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194796 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204797
4798 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204800
4801 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014802 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204803
4804 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524805 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474806 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524807 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204808 EXPECT_EQ(2, response2->headers->GetContentLength());
4809
4810 LoadTimingInfo load_timing_info2;
4811 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4812 TestLoadTimingReused(load_timing_info2);
4813
4814 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4815
4816 trans2.reset();
4817 session->CloseAllConnections();
4818}
4819
4820// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014821TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204822 HttpRequestInfo request1;
4823 request1.method = "GET";
bncce36dca22015-04-21 22:11:234824 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104825 request1.traffic_annotation =
4826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204827
4828 HttpRequestInfo request2;
4829 request2.method = "GET";
bncce36dca22015-04-21 22:11:234830 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104831 request2.traffic_annotation =
4832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204833
4834 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594835 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494836 ProxyResolutionService::CreateFixedFromPacResult(
4837 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514838 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074839 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204841
4842 // Since we have proxy, should try to establish tunnel.
4843 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174844 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4845 "Host: www.example.org:443\r\n"
4846 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204847
rsleevidb16bb02015-11-12 23:47:174848 MockWrite("GET /1 HTTP/1.1\r\n"
4849 "Host: www.example.org\r\n"
4850 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204851
rsleevidb16bb02015-11-12 23:47:174852 MockWrite("GET /2 HTTP/1.1\r\n"
4853 "Host: www.example.org\r\n"
4854 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204855 };
4856
4857 // The proxy responds to the connect with a 407, using a persistent
4858 // connection.
4859 MockRead data_reads1[] = {
4860 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4861
4862 MockRead("HTTP/1.1 200 OK\r\n"),
4863 MockRead("Content-Length: 1\r\n\r\n"),
4864 MockRead(SYNCHRONOUS, "1"),
4865
4866 MockRead("HTTP/1.1 200 OK\r\n"),
4867 MockRead("Content-Length: 2\r\n\r\n"),
4868 MockRead(SYNCHRONOUS, "22"),
4869 };
4870
Ryan Sleevib8d7ea02018-05-07 20:01:014871 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204873 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204875
4876 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584877 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204879
4880 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204882
4883 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014884 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204885
4886 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524887 ASSERT_TRUE(response1);
4888 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204889 EXPECT_EQ(1, response1->headers->GetContentLength());
4890
4891 LoadTimingInfo load_timing_info1;
4892 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4893 TestLoadTimingNotReusedWithPac(load_timing_info1,
4894 CONNECT_TIMING_HAS_SSL_TIMES);
4895
4896 trans1.reset();
4897
4898 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584899 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194900 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204901
4902 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204904
4905 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014906 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204907
4908 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524909 ASSERT_TRUE(response2);
4910 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204911 EXPECT_EQ(2, response2->headers->GetContentLength());
4912
4913 LoadTimingInfo load_timing_info2;
4914 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4915 TestLoadTimingReusedWithPac(load_timing_info2);
4916
4917 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4918
4919 trans2.reset();
4920 session->CloseAllConnections();
4921}
4922
[email protected]2df19bb2010-08-25 20:13:464923// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014924TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274925 HttpRequestInfo request;
4926 request.method = "GET";
bncce36dca22015-04-21 22:11:234927 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104928 request.traffic_annotation =
4929 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274930
[email protected]2df19bb2010-08-25 20:13:464931 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494932 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4933 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514934 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074935 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464937
[email protected]2df19bb2010-08-25 20:13:464938 // Since we have proxy, should use full url
4939 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234940 MockWrite(
4941 "GET http://www.example.org/ HTTP/1.1\r\n"
4942 "Host: www.example.org\r\n"
4943 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464944 };
4945
4946 MockRead data_reads1[] = {
4947 MockRead("HTTP/1.1 200 OK\r\n"),
4948 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4949 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064950 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464951 };
4952
Ryan Sleevib8d7ea02018-05-07 20:01:014953 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074954 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064955 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074956 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464957
[email protected]49639fa2011-12-20 23:22:414958 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464959
bnc691fda62016-08-12 00:43:164960 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504961
bnc691fda62016-08-12 00:43:164962 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464964
4965 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014966 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464967
[email protected]58e32bb2013-01-21 18:23:254968 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164969 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254970 TestLoadTimingNotReused(load_timing_info,
4971 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4972
bnc691fda62016-08-12 00:43:164973 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524974 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464975
tbansal2ecbbc72016-10-06 17:15:474976 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464977 EXPECT_TRUE(response->headers->IsKeepAlive());
4978 EXPECT_EQ(200, response->headers->response_code());
4979 EXPECT_EQ(100, response->headers->GetContentLength());
4980 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4981
4982 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524983 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464984}
4985
[email protected]7642b5ae2010-09-01 20:55:174986// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014987TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274988 HttpRequestInfo request;
4989 request.method = "GET";
bncce36dca22015-04-21 22:11:234990 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104991 request.traffic_annotation =
4992 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274993
[email protected]7642b5ae2010-09-01 20:55:174994 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494995 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4996 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514997 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074998 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175000
bncce36dca22015-04-21 22:11:235001 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415002 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455003 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415004 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175005
bnc42331402016-07-25 13:36:155006 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415007 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175008 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415009 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175010 };
5011
Ryan Sleevib8d7ea02018-05-07 20:01:015012 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075013 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175014
[email protected]8ddf8322012-02-23 18:08:065015 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365016 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075017 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175018
[email protected]49639fa2011-12-20 23:22:415019 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175020
bnc691fda62016-08-12 00:43:165021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505022
bnc691fda62016-08-12 00:43:165023 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175025
5026 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015027 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175028
[email protected]58e32bb2013-01-21 18:23:255029 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165030 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255031 TestLoadTimingNotReused(load_timing_info,
5032 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5033
bnc691fda62016-08-12 00:43:165034 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525035 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475036 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525037 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025038 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175039
5040 std::string response_data;
bnc691fda62016-08-12 00:43:165041 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235042 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175043}
5044
[email protected]1c173852014-06-19 12:51:505045// Verifies that a session which races and wins against the owning transaction
5046// (completing prior to host resolution), doesn't fail the transaction.
5047// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015048TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505049 HttpRequestInfo request;
5050 request.method = "GET";
bncce36dca22015-04-21 22:11:235051 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105052 request.traffic_annotation =
5053 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505054
5055 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495056 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5057 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515058 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505059 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095060 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505061
bncce36dca22015-04-21 22:11:235062 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415063 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455064 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415065 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505066
bnc42331402016-07-25 13:36:155067 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415068 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505069 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415070 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505071 };
5072
Ryan Sleevib8d7ea02018-05-07 20:01:015073 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505074 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5075
5076 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365077 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5079
5080 TestCompletionCallback callback1;
5081
bnc691fda62016-08-12 00:43:165082 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505083
5084 // Stall the hostname resolution begun by the transaction.
5085 session_deps_.host_resolver->set_synchronous_mode(false);
5086 session_deps_.host_resolver->set_ondemand_mode(true);
5087
bnc691fda62016-08-12 00:43:165088 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505090
5091 // Race a session to the proxy, which completes first.
5092 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045093 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5094 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505095 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525096 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505097
5098 // Unstall the resolution begun by the transaction.
5099 session_deps_.host_resolver->set_ondemand_mode(true);
5100 session_deps_.host_resolver->ResolveAllPending();
5101
5102 EXPECT_FALSE(callback1.have_result());
5103 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015104 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505105
bnc691fda62016-08-12 00:43:165106 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525107 ASSERT_TRUE(response);
5108 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025109 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505110
5111 std::string response_data;
bnc691fda62016-08-12 00:43:165112 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505113 EXPECT_EQ(kUploadData, response_data);
5114}
5115
[email protected]dc7bd1c52010-11-12 00:01:135116// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015117TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275118 HttpRequestInfo request;
5119 request.method = "GET";
bncce36dca22015-04-21 22:11:235120 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105121 request.traffic_annotation =
5122 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275123
[email protected]79cb5c12011-09-12 13:12:045124 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495125 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5126 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515127 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075128 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095129 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135130
[email protected]dc7bd1c52010-11-12 00:01:135131 // The first request will be a bare GET, the second request will be a
5132 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455133 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415134 SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485135 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385136 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135137 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465138 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135139 };
bncdf80d44fd2016-07-15 20:27:415140 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5141 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485142 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135143 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415144 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135145 };
5146
5147 // The first response is a 407 proxy authentication challenge, and the second
5148 // response will be a 200 response since the second request includes a valid
5149 // Authorization header.
5150 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465151 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135152 };
bnc42331402016-07-25 13:36:155153 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235154 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415155 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5156 SpdySerializedFrame body_authentication(
5157 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155158 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415159 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135160 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415161 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465162 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415163 CreateMockRead(resp_data, 4),
5164 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135165 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135166 };
5167
Ryan Sleevib8d7ea02018-05-07 20:01:015168 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075169 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135170
[email protected]8ddf8322012-02-23 18:08:065171 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365172 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075173 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135174
[email protected]49639fa2011-12-20 23:22:415175 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135176
bnc691fda62016-08-12 00:43:165177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135178
bnc691fda62016-08-12 00:43:165179 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015180 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135181
5182 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015183 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135184
bnc691fda62016-08-12 00:43:165185 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135186
wezca1070932016-05-26 20:30:525187 ASSERT_TRUE(response);
5188 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135189 EXPECT_EQ(407, response->headers->response_code());
5190 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435191 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135192
[email protected]49639fa2011-12-20 23:22:415193 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135194
bnc691fda62016-08-12 00:43:165195 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015196 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135197
5198 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015199 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135200
bnc691fda62016-08-12 00:43:165201 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135202
wezca1070932016-05-26 20:30:525203 ASSERT_TRUE(response_restart);
5204 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135205 EXPECT_EQ(200, response_restart->headers->response_code());
5206 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525207 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135208}
5209
[email protected]d9da5fe2010-10-13 22:37:165210// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015211TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275212 HttpRequestInfo request;
5213 request.method = "GET";
bncce36dca22015-04-21 22:11:235214 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105215 request.traffic_annotation =
5216 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275217
[email protected]d9da5fe2010-10-13 22:37:165218 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495219 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5220 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515221 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075222 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165224
bnc691fda62016-08-12 00:43:165225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165226
bncce36dca22015-04-21 22:11:235227 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415228 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235229 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5230 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165231
bncce36dca22015-04-21 22:11:235232 const char get[] =
5233 "GET / HTTP/1.1\r\n"
5234 "Host: www.example.org\r\n"
5235 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415236 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195237 spdy_util_.ConstructSpdyDataFrame(1, get, false));
bnc42331402016-07-25 13:36:155238 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165239 const char resp[] = "HTTP/1.1 200 OK\r\n"
5240 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415241 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195242 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
bncdf80d44fd2016-07-15 20:27:415243 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195244 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
bncdf80d44fd2016-07-15 20:27:415245 SpdySerializedFrame window_update(
5246 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045247
5248 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415249 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5250 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045251 };
5252
[email protected]d9da5fe2010-10-13 22:37:165253 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415254 CreateMockRead(conn_resp, 1, ASYNC),
5255 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5256 CreateMockRead(wrapped_body, 4, ASYNC),
5257 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135258 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165259 };
5260
Ryan Sleevib8d7ea02018-05-07 20:01:015261 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075262 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165263
[email protected]8ddf8322012-02-23 18:08:065264 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365265 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065267 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075268 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165269
[email protected]49639fa2011-12-20 23:22:415270 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165271
bnc691fda62016-08-12 00:43:165272 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165274
5275 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015276 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165277
[email protected]58e32bb2013-01-21 18:23:255278 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165279 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255280 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5281
bnc691fda62016-08-12 00:43:165282 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525283 ASSERT_TRUE(response);
5284 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165285 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5286
5287 std::string response_data;
bnc691fda62016-08-12 00:43:165288 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165289 EXPECT_EQ("1234567890", response_data);
5290}
5291
5292// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015293TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5294 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385295
[email protected]cb9bf6ca2011-01-28 13:15:275296 HttpRequestInfo request;
5297 request.method = "GET";
bncce36dca22015-04-21 22:11:235298 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105299 request.traffic_annotation =
5300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275301
[email protected]d9da5fe2010-10-13 22:37:165302 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495303 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5304 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515305 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075306 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095307 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165308
bnc691fda62016-08-12 00:43:165309 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165310
bncce36dca22015-04-21 22:11:235311 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415312 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235313 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5314 // fetch https://www.example.org/ via SPDY
5315 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415316 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495317 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415318 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155319 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415320 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155321 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415322 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025323 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415324 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5325 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025326 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415327 SpdySerializedFrame window_update_get_resp(
5328 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5329 SpdySerializedFrame window_update_body(
5330 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045331
5332 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415333 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5334 CreateMockWrite(window_update_get_resp, 6),
5335 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045336 };
5337
[email protected]d9da5fe2010-10-13 22:37:165338 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415339 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095340 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415341 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5342 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135343 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165344 };
5345
Ryan Sleevib8d7ea02018-05-07 20:01:015346 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075347 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165348
[email protected]8ddf8322012-02-23 18:08:065349 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365350 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065352 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365353 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165355
[email protected]49639fa2011-12-20 23:22:415356 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165357
bnc691fda62016-08-12 00:43:165358 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165360
rch32320842015-05-16 15:57:095361 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555362 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095363 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595364 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165365 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015366 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165367
[email protected]58e32bb2013-01-21 18:23:255368 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165369 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255370 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5371
bnc691fda62016-08-12 00:43:165372 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525373 ASSERT_TRUE(response);
5374 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025375 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165376
5377 std::string response_data;
bnc691fda62016-08-12 00:43:165378 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235379 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165380}
5381
5382// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015383TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275384 HttpRequestInfo request;
5385 request.method = "GET";
bncce36dca22015-04-21 22:11:235386 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105387 request.traffic_annotation =
5388 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275389
[email protected]d9da5fe2010-10-13 22:37:165390 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495391 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5392 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515393 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075394 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165396
bnc691fda62016-08-12 00:43:165397 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165398
bncce36dca22015-04-21 22:11:235399 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415400 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235401 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415402 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085403 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165404
5405 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415406 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165407 };
5408
bnc42331402016-07-25 13:36:155409 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415410 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165411 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415412 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165413 };
5414
Ryan Sleevib8d7ea02018-05-07 20:01:015415 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075416 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165417
[email protected]8ddf8322012-02-23 18:08:065418 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365419 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065421 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365422 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165424
[email protected]49639fa2011-12-20 23:22:415425 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165426
bnc691fda62016-08-12 00:43:165427 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165429
5430 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015431 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165432
ttuttle960fcbf2016-04-19 13:26:325433 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165434}
5435
[email protected]f6c63db52013-02-02 00:35:225436// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5437// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015438TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225439 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5440 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495441 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5442 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515443 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075444 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095445 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505446 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225447
5448 HttpRequestInfo request1;
5449 request1.method = "GET";
bncce36dca22015-04-21 22:11:235450 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225451 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105452 request1.traffic_annotation =
5453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225454
5455 HttpRequestInfo request2;
5456 request2.method = "GET";
bncce36dca22015-04-21 22:11:235457 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225458 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105459 request2.traffic_annotation =
5460 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225461
bncce36dca22015-04-21 22:11:235462 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415463 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235464 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155465 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225466
bncce36dca22015-04-21 22:11:235467 // Fetch https://www.example.org/ via HTTP.
5468 const char get1[] =
5469 "GET / HTTP/1.1\r\n"
5470 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225471 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415472 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195473 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225474 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5475 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415476 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195477 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415478 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195479 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415480 SpdySerializedFrame window_update(
5481 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225482
bncce36dca22015-04-21 22:11:235483 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295484 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275485 connect2_block[kHttp2MethodHeader] = "CONNECT";
5486 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155487 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5488 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395489
bnc42331402016-07-25 13:36:155490 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225491
bncce36dca22015-04-21 22:11:235492 // Fetch https://mail.example.org/ via HTTP.
5493 const char get2[] =
5494 "GET / HTTP/1.1\r\n"
5495 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225496 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415497 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195498 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225499 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5500 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415501 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195502 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
bncdf80d44fd2016-07-15 20:27:415503 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195504 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225505
5506 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415507 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5508 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225509 };
5510
5511 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415512 CreateMockRead(conn_resp1, 1, ASYNC),
5513 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5514 CreateMockRead(wrapped_body1, 4, ASYNC),
5515 CreateMockRead(conn_resp2, 6, ASYNC),
5516 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5517 CreateMockRead(wrapped_body2, 9, ASYNC),
5518 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225519 };
5520
Ryan Sleevib8d7ea02018-05-07 20:01:015521 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505522 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225523
5524 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365525 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225527 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505528 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225529 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225531
5532 TestCompletionCallback callback;
5533
bnc691fda62016-08-12 00:43:165534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205535 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015536 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225537
5538 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165539 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225540 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5541
bnc691fda62016-08-12 00:43:165542 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525543 ASSERT_TRUE(response);
5544 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225545 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5546
5547 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295548 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165549 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505550 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225551
bnc691fda62016-08-12 00:43:165552 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205553 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015554 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225555
5556 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165557 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225558 // Even though the SPDY connection is reused, a new tunnelled connection has
5559 // to be created, so the socket's load timing looks like a fresh connection.
5560 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5561
5562 // The requests should have different IDs, since they each are using their own
5563 // separate stream.
5564 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5565
bnc691fda62016-08-12 00:43:165566 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505567 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225568}
5569
5570// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5571// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015572TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225573 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5574 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495575 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5576 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515577 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075578 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095579 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505580 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225581
5582 HttpRequestInfo request1;
5583 request1.method = "GET";
bncce36dca22015-04-21 22:11:235584 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225585 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105586 request1.traffic_annotation =
5587 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225588
5589 HttpRequestInfo request2;
5590 request2.method = "GET";
bncce36dca22015-04-21 22:11:235591 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225592 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105593 request2.traffic_annotation =
5594 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225595
bncce36dca22015-04-21 22:11:235596 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415597 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235598 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155599 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225600
bncce36dca22015-04-21 22:11:235601 // Fetch https://www.example.org/ via HTTP.
5602 const char get1[] =
5603 "GET / HTTP/1.1\r\n"
5604 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225605 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415606 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195607 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225608 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5609 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415610 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195611 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415612 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195613 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415614 SpdySerializedFrame window_update(
5615 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225616
bncce36dca22015-04-21 22:11:235617 // Fetch https://www.example.org/2 via HTTP.
5618 const char get2[] =
5619 "GET /2 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";
bncdf80d44fd2016-07-15 20:27:415622 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195623 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225624 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5625 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415626 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195627 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
bncdf80d44fd2016-07-15 20:27:415628 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195629 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225630
5631 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415632 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5633 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225634 };
5635
5636 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415637 CreateMockRead(conn_resp1, 1, ASYNC),
5638 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465639 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415640 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465641 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415642 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225643 };
5644
Ryan Sleevib8d7ea02018-05-07 20:01:015645 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505646 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225647
5648 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365649 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505650 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225651 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505652 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225653
5654 TestCompletionCallback callback;
5655
bnc87dcefc2017-05-25 12:47:585656 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195657 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205658 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225660
5661 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015662 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225663
5664 LoadTimingInfo load_timing_info;
5665 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5666 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5667
5668 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525669 ASSERT_TRUE(response);
5670 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225671 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5672
5673 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295674 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505675 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225676 trans.reset();
5677
bnc87dcefc2017-05-25 12:47:585678 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195679 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205680 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225682
[email protected]f6c63db52013-02-02 00:35:225683 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015684 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225685
5686 LoadTimingInfo load_timing_info2;
5687 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5688 TestLoadTimingReused(load_timing_info2);
5689
5690 // The requests should have the same ID.
5691 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5692
[email protected]90499482013-06-01 00:39:505693 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225694}
5695
5696// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5697// Proxy to different servers.
bncd16676a2016-07-20 16:23:015698TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225699 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495700 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5701 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515702 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075703 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095704 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505705 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225706
5707 HttpRequestInfo request1;
5708 request1.method = "GET";
bncce36dca22015-04-21 22:11:235709 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225710 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105711 request1.traffic_annotation =
5712 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225713
5714 HttpRequestInfo request2;
5715 request2.method = "GET";
bncce36dca22015-04-21 22:11:235716 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225717 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105718 request2.traffic_annotation =
5719 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225720
bncce36dca22015-04-21 22:11:235721 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265722 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235723 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415724 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155725 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5726 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Bence Békyd74f4382018-02-20 18:26:195727 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385728 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225729
bncce36dca22015-04-21 22:11:235730 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265731 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235732 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415733 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155734 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5735 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
Bence Békyd74f4382018-02-20 18:26:195736 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225737
5738 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415739 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225740 };
5741
5742 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415743 CreateMockRead(get_resp1, 1, ASYNC),
5744 CreateMockRead(body1, 2, ASYNC),
5745 CreateMockRead(get_resp2, 4, ASYNC),
5746 CreateMockRead(body2, 5, ASYNC),
5747 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225748 };
5749
Ryan Sleevib8d7ea02018-05-07 20:01:015750 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505751 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225752
5753 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365754 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225756
5757 TestCompletionCallback callback;
5758
bnc87dcefc2017-05-25 12:47:585759 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195760 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205761 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015762 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225763
5764 LoadTimingInfo load_timing_info;
5765 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5766 TestLoadTimingNotReused(load_timing_info,
5767 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5768
5769 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525770 ASSERT_TRUE(response);
5771 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025772 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225773
5774 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295775 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505776 rv = trans->Read(buf.get(), 256, callback.callback());
5777 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225778 // Delete the first request, so the second one can reuse the socket.
5779 trans.reset();
5780
bnc691fda62016-08-12 00:43:165781 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205782 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015783 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225784
5785 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165786 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225787 TestLoadTimingReused(load_timing_info2);
5788
5789 // The requests should have the same ID.
5790 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5791
bnc691fda62016-08-12 00:43:165792 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505793 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225794}
5795
[email protected]2df19bb2010-08-25 20:13:465796// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015797TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465798 HttpRequestInfo request;
5799 request.method = "GET";
bncce36dca22015-04-21 22:11:235800 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465801 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295802 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:105803 request.traffic_annotation =
5804 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465805
[email protected]79cb5c12011-09-12 13:12:045806 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495807 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5808 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515809 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075810 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275812
[email protected]2df19bb2010-08-25 20:13:465813 // Since we have proxy, should use full url
5814 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165815 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5816 "Host: www.example.org\r\n"
5817 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465818
bnc691fda62016-08-12 00:43:165819 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235820 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165821 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5822 "Host: www.example.org\r\n"
5823 "Proxy-Connection: keep-alive\r\n"
5824 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465825 };
5826
5827 // The proxy responds to the GET with a 407, using a persistent
5828 // connection.
5829 MockRead data_reads1[] = {
5830 // No credentials.
5831 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5832 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5833 MockRead("Proxy-Connection: keep-alive\r\n"),
5834 MockRead("Content-Length: 0\r\n\r\n"),
5835
5836 MockRead("HTTP/1.1 200 OK\r\n"),
5837 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5838 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065839 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465840 };
5841
Ryan Sleevib8d7ea02018-05-07 20:01:015842 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075843 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065844 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465846
[email protected]49639fa2011-12-20 23:22:415847 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465848
bnc691fda62016-08-12 00:43:165849 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505850
bnc691fda62016-08-12 00:43:165851 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465853
5854 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015855 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465856
[email protected]58e32bb2013-01-21 18:23:255857 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165858 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255859 TestLoadTimingNotReused(load_timing_info,
5860 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5861
bnc691fda62016-08-12 00:43:165862 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525863 ASSERT_TRUE(response);
5864 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465865 EXPECT_EQ(407, response->headers->response_code());
5866 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435867 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465868
[email protected]49639fa2011-12-20 23:22:415869 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465870
bnc691fda62016-08-12 00:43:165871 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465873
5874 rv = callback2.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 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165878 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255879 // Retrying with HTTP AUTH is considered to be reusing a socket.
5880 TestLoadTimingReused(load_timing_info);
5881
bnc691fda62016-08-12 00:43:165882 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525883 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465884
5885 EXPECT_TRUE(response->headers->IsKeepAlive());
5886 EXPECT_EQ(200, response->headers->response_code());
5887 EXPECT_EQ(100, response->headers->GetContentLength());
5888 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5889
5890 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525891 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465892}
5893
[email protected]23e482282013-06-14 16:08:025894void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085895 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425896 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085897 request.method = "GET";
bncce36dca22015-04-21 22:11:235898 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105899 request.traffic_annotation =
5900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:085901
[email protected]cb9bf6ca2011-01-28 13:15:275902 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495903 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5904 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:095905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275906
[email protected]c744cf22009-02-27 07:28:085907 // Since we have proxy, should try to establish tunnel.
5908 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175909 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5910 "Host: www.example.org:443\r\n"
5911 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085912 };
5913
5914 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235915 status, MockRead("Content-Length: 10\r\n\r\n"),
5916 // No response body because the test stops reading here.
5917 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085918 };
5919
Ryan Sleevib8d7ea02018-05-07 20:01:015920 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:075921 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085922
[email protected]49639fa2011-12-20 23:22:415923 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085924
bnc691fda62016-08-12 00:43:165925 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505926
tfarina42834112016-09-22 13:38:205927 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015928 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085929
5930 rv = callback.WaitForResult();
5931 EXPECT_EQ(expected_status, rv);
5932}
5933
[email protected]23e482282013-06-14 16:08:025934void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235935 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085936 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425937 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085938}
5939
bncd16676a2016-07-20 16:23:015940TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085941 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5942}
5943
bncd16676a2016-07-20 16:23:015944TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085945 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5946}
5947
bncd16676a2016-07-20 16:23:015948TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085949 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5950}
5951
bncd16676a2016-07-20 16:23:015952TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085953 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5954}
5955
bncd16676a2016-07-20 16:23:015956TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085957 ConnectStatusHelper(
5958 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5959}
5960
bncd16676a2016-07-20 16:23:015961TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085962 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5963}
5964
bncd16676a2016-07-20 16:23:015965TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085966 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5967}
5968
bncd16676a2016-07-20 16:23:015969TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085970 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5971}
5972
bncd16676a2016-07-20 16:23:015973TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085974 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5975}
5976
bncd16676a2016-07-20 16:23:015977TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085978 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5979}
5980
bncd16676a2016-07-20 16:23:015981TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085982 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5983}
5984
bncd16676a2016-07-20 16:23:015985TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085986 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5987}
5988
bncd16676a2016-07-20 16:23:015989TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085990 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5991}
5992
bncd16676a2016-07-20 16:23:015993TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085994 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5995}
5996
bncd16676a2016-07-20 16:23:015997TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085998 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5999}
6000
bncd16676a2016-07-20 16:23:016001TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086002 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6003}
6004
bncd16676a2016-07-20 16:23:016005TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376006 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6007}
6008
bncd16676a2016-07-20 16:23:016009TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086010 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6011}
6012
bncd16676a2016-07-20 16:23:016013TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086014 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6015}
6016
bncd16676a2016-07-20 16:23:016017TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086018 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6019}
6020
bncd16676a2016-07-20 16:23:016021TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086022 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6023}
6024
bncd16676a2016-07-20 16:23:016025TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086026 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6027}
6028
bncd16676a2016-07-20 16:23:016029TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086030 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6031}
6032
bncd16676a2016-07-20 16:23:016033TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086034 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6035}
6036
bncd16676a2016-07-20 16:23:016037TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086038 ConnectStatusHelperWithExpectedStatus(
6039 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546040 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086041}
6042
bncd16676a2016-07-20 16:23:016043TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086044 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6045}
6046
bncd16676a2016-07-20 16:23:016047TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086048 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6049}
6050
bncd16676a2016-07-20 16:23:016051TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086052 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6053}
6054
bncd16676a2016-07-20 16:23:016055TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086056 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6057}
6058
bncd16676a2016-07-20 16:23:016059TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086060 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6061}
6062
bncd16676a2016-07-20 16:23:016063TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086064 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6065}
6066
bncd16676a2016-07-20 16:23:016067TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086068 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6069}
6070
bncd16676a2016-07-20 16:23:016071TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086072 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6073}
6074
bncd16676a2016-07-20 16:23:016075TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086076 ConnectStatusHelper(
6077 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6078}
6079
bncd16676a2016-07-20 16:23:016080TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086081 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6082}
6083
bncd16676a2016-07-20 16:23:016084TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086085 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6086}
6087
bncd16676a2016-07-20 16:23:016088TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086089 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6090}
6091
bncd16676a2016-07-20 16:23:016092TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086093 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6094}
6095
bncd16676a2016-07-20 16:23:016096TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086097 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6098}
6099
bncd16676a2016-07-20 16:23:016100TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086101 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6102}
6103
bncd16676a2016-07-20 16:23:016104TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086105 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6106}
6107
[email protected]038e9a32008-10-08 22:40:166108// Test the flow when both the proxy server AND origin server require
6109// authentication. Again, this uses basic auth for both since that is
6110// the simplest to mock.
bncd16676a2016-07-20 16:23:016111TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276112 HttpRequestInfo request;
6113 request.method = "GET";
bncce36dca22015-04-21 22:11:236114 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106115 request.traffic_annotation =
6116 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276117
[email protected]038e9a32008-10-08 22:40:166118 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496119 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6120 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096121 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076122
bnc691fda62016-08-12 00:43:166123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166124
[email protected]f9ee6b52008-11-08 06:46:236125 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236126 MockWrite(
6127 "GET http://www.example.org/ HTTP/1.1\r\n"
6128 "Host: www.example.org\r\n"
6129 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236130 };
6131
[email protected]038e9a32008-10-08 22:40:166132 MockRead data_reads1[] = {
6133 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6134 // Give a couple authenticate options (only the middle one is actually
6135 // supported).
[email protected]22927ad2009-09-21 19:56:196136 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166137 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6138 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6139 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6140 // Large content-length -- won't matter, as connection will be reset.
6141 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066142 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166143 };
6144
bnc691fda62016-08-12 00:43:166145 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166146 // request we should be issuing -- the final header line contains the
6147 // proxy's credentials.
6148 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236149 MockWrite(
6150 "GET http://www.example.org/ HTTP/1.1\r\n"
6151 "Host: www.example.org\r\n"
6152 "Proxy-Connection: keep-alive\r\n"
6153 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166154 };
6155
6156 // Now the proxy server lets the request pass through to origin server.
6157 // The origin server responds with a 401.
6158 MockRead data_reads2[] = {
6159 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6160 // Note: We are using the same realm-name as the proxy server. This is
6161 // completely valid, as realms are unique across hosts.
6162 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6163 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6164 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066165 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166166 };
6167
bnc691fda62016-08-12 00:43:166168 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166169 // the credentials for both the proxy and origin server.
6170 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236171 MockWrite(
6172 "GET http://www.example.org/ HTTP/1.1\r\n"
6173 "Host: www.example.org\r\n"
6174 "Proxy-Connection: keep-alive\r\n"
6175 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6176 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166177 };
6178
6179 // Lastly we get the desired content.
6180 MockRead data_reads3[] = {
6181 MockRead("HTTP/1.0 200 OK\r\n"),
6182 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6183 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066184 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166185 };
6186
Ryan Sleevib8d7ea02018-05-07 20:01:016187 StaticSocketDataProvider data1(data_reads1, data_writes1);
6188 StaticSocketDataProvider data2(data_reads2, data_writes2);
6189 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6191 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6192 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166193
[email protected]49639fa2011-12-20 23:22:416194 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166195
tfarina42834112016-09-22 13:38:206196 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166198
6199 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016200 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166201
bnc691fda62016-08-12 00:43:166202 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526203 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046204 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166205
[email protected]49639fa2011-12-20 23:22:416206 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166207
bnc691fda62016-08-12 00:43:166208 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166210
6211 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016212 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166213
bnc691fda62016-08-12 00:43:166214 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526215 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046216 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166217
[email protected]49639fa2011-12-20 23:22:416218 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166219
bnc691fda62016-08-12 00:43:166220 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6221 callback3.callback());
robpercival214763f2016-07-01 23:27:016222 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166223
6224 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016225 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166226
bnc691fda62016-08-12 00:43:166227 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526228 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166229 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166230}
[email protected]4ddaf2502008-10-23 18:26:196231
[email protected]ea9dc9a2009-09-05 00:43:326232// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6233// can't hook into its internals to cause it to generate predictable NTLM
6234// authorization headers.
6235#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376236// The NTLM authentication unit tests are based on known test data from the
6237// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6238// flow rather than the implementation of the NTLM protocol. See net/ntlm
6239// for the implementation and testing of the protocol.
6240//
6241// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296242
6243// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556244TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426245 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246246 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556247 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106248 request.traffic_annotation =
6249 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546250
6251 // Ensure load is not disrupted by flags which suppress behaviour specific
6252 // to other auth schemes.
6253 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246254
Zentaro Kavanagh6ccee512017-09-28 18:34:096255 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6256 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276258
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376259 // Generate the NTLM messages based on known test data.
6260 std::string negotiate_msg;
6261 std::string challenge_msg;
6262 std::string authenticate_msg;
6263 base::Base64Encode(
6264 base::StringPiece(
6265 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6266 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6267 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556268 base::Base64Encode(
6269 base::StringPiece(
6270 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6271 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6272 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376273 base::Base64Encode(
6274 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096275 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556276 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6277 arraysize(
6278 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376279 &authenticate_msg);
6280
[email protected]3f918782009-02-28 01:29:246281 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556282 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6283 "Host: server\r\n"
6284 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246285 };
6286
6287 MockRead data_reads1[] = {
6288 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046289 // Negotiate and NTLM are often requested together. However, we only want
6290 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6291 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246292 MockRead("WWW-Authenticate: NTLM\r\n"),
6293 MockRead("Connection: close\r\n"),
6294 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366295 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246296 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246297 };
6298
6299 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166300 // After restarting with a null identity, this is the
6301 // request we should be issuing -- the final header line contains a Type
6302 // 1 message.
6303 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556304 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166305 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376306 "Authorization: NTLM "),
6307 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246308
bnc691fda62016-08-12 00:43:166309 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376310 // (using correct credentials). The second request continues on the
6311 // same connection.
bnc691fda62016-08-12 00:43:166312 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556313 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166314 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376315 "Authorization: NTLM "),
6316 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246317 };
6318
6319 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026320 // The origin server responds with a Type 2 message.
6321 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376322 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6323 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026324 MockRead("Content-Type: text/html\r\n\r\n"),
6325 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246326
Bence Béky1e4ef192017-09-18 19:58:026327 // Lastly we get the desired content.
6328 MockRead("HTTP/1.1 200 OK\r\n"),
6329 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6330 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246331 };
6332
Ryan Sleevib8d7ea02018-05-07 20:01:016333 StaticSocketDataProvider data1(data_reads1, data_writes1);
6334 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:076335 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6336 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246337
Bence Béky83eb3512017-09-05 12:56:096338 SSLSocketDataProvider ssl1(ASYNC, OK);
6339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6340 SSLSocketDataProvider ssl2(ASYNC, OK);
6341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6342
[email protected]49639fa2011-12-20 23:22:416343 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246344
bnc691fda62016-08-12 00:43:166345 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506346
tfarina42834112016-09-22 13:38:206347 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246349
6350 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016351 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246352
bnc691fda62016-08-12 00:43:166353 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226354
bnc691fda62016-08-12 00:43:166355 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526356 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046357 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246358
[email protected]49639fa2011-12-20 23:22:416359 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256360
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376361 rv = trans.RestartWithAuth(
6362 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6363 callback2.callback());
robpercival214763f2016-07-01 23:27:016364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256365
6366 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016367 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256368
bnc691fda62016-08-12 00:43:166369 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256370
bnc691fda62016-08-12 00:43:166371 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526372 ASSERT_TRUE(response);
6373 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256374
[email protected]49639fa2011-12-20 23:22:416375 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246376
bnc691fda62016-08-12 00:43:166377 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246379
[email protected]0757e7702009-03-27 04:00:226380 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016381 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246382
bnc691fda62016-08-12 00:43:166383 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526384 ASSERT_TRUE(response);
6385 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026386 EXPECT_EQ(14, response->headers->GetContentLength());
6387
6388 std::string response_data;
6389 rv = ReadTransaction(&trans, &response_data);
6390 EXPECT_THAT(rv, IsOk());
6391 EXPECT_EQ("Please Login\r\n", response_data);
6392
6393 EXPECT_TRUE(data1.AllReadDataConsumed());
6394 EXPECT_TRUE(data1.AllWriteDataConsumed());
6395 EXPECT_TRUE(data2.AllReadDataConsumed());
6396 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246397}
6398
[email protected]385a4672009-03-11 22:21:296399// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556400TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426401 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296402 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556403 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106404 request.traffic_annotation =
6405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296406
Zentaro Kavanagh6ccee512017-09-28 18:34:096407 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6408 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096409 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276410
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376411 // Generate the NTLM messages based on known test data.
6412 std::string negotiate_msg;
6413 std::string challenge_msg;
6414 std::string authenticate_msg;
6415 base::Base64Encode(
6416 base::StringPiece(
6417 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6418 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6419 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556420 base::Base64Encode(
6421 base::StringPiece(
6422 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6423 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6424 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376425 base::Base64Encode(
6426 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096427 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556428 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6429 arraysize(
6430 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376431 &authenticate_msg);
6432
6433 // The authenticate message when |kWrongPassword| is sent.
6434 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556435 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6436 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6437 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6438 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6439 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6440 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376441
Zentaro Kavanagh1890a3d2018-01-29 19:52:556442 // Sanity check that it's the same length as the correct authenticate message
6443 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376444 ASSERT_EQ(authenticate_msg.length(),
6445 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556446 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376447
[email protected]385a4672009-03-11 22:21:296448 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556449 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6450 "Host: server\r\n"
6451 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296452 };
6453
6454 MockRead data_reads1[] = {
6455 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046456 // Negotiate and NTLM are often requested together. However, we only want
6457 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6458 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296459 MockRead("WWW-Authenticate: NTLM\r\n"),
6460 MockRead("Connection: close\r\n"),
6461 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366462 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296463 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296464 };
6465
6466 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166467 // After restarting with a null identity, this is the
6468 // request we should be issuing -- the final header line contains a Type
6469 // 1 message.
6470 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556471 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166472 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376473 "Authorization: NTLM "),
6474 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296475
bnc691fda62016-08-12 00:43:166476 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376477 // (using incorrect credentials). The second request continues on the
6478 // same connection.
bnc691fda62016-08-12 00:43:166479 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556480 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166481 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376482 "Authorization: NTLM "),
6483 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296484 };
6485
6486 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376487 // The origin server responds with a Type 2 message.
6488 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6489 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6490 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6491 MockRead("Content-Type: text/html\r\n\r\n"),
6492 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296493
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376494 // Wrong password.
6495 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6496 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6497 MockRead("Content-Length: 42\r\n"),
6498 MockRead("Content-Type: text/html\r\n\r\n"),
6499 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296500 };
6501
6502 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166503 // After restarting with a null identity, this is the
6504 // request we should be issuing -- the final header line contains a Type
6505 // 1 message.
6506 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556507 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166508 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376509 "Authorization: NTLM "),
6510 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296511
bnc691fda62016-08-12 00:43:166512 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6513 // (the credentials for the origin server). The second request continues
6514 // on the same connection.
6515 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556516 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166517 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376518 "Authorization: NTLM "),
6519 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296520 };
6521
6522 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026523 // The origin server responds with a Type 2 message.
6524 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376525 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6526 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026527 MockRead("Content-Type: text/html\r\n\r\n"),
6528 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296529
Bence Béky1e4ef192017-09-18 19:58:026530 // Lastly we get the desired content.
6531 MockRead("HTTP/1.1 200 OK\r\n"),
6532 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6533 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296534 };
6535
Ryan Sleevib8d7ea02018-05-07 20:01:016536 StaticSocketDataProvider data1(data_reads1, data_writes1);
6537 StaticSocketDataProvider data2(data_reads2, data_writes2);
6538 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076539 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6540 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6541 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296542
Bence Béky83eb3512017-09-05 12:56:096543 SSLSocketDataProvider ssl1(ASYNC, OK);
6544 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6545 SSLSocketDataProvider ssl2(ASYNC, OK);
6546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6547 SSLSocketDataProvider ssl3(ASYNC, OK);
6548 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6549
[email protected]49639fa2011-12-20 23:22:416550 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296551
bnc691fda62016-08-12 00:43:166552 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506553
tfarina42834112016-09-22 13:38:206554 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296556
6557 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016558 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296559
bnc691fda62016-08-12 00:43:166560 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296561
bnc691fda62016-08-12 00:43:166562 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526563 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046564 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296565
[email protected]49639fa2011-12-20 23:22:416566 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296567
[email protected]0757e7702009-03-27 04:00:226568 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376569 rv = trans.RestartWithAuth(
6570 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6571 callback2.callback());
robpercival214763f2016-07-01 23:27:016572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296573
[email protected]10af5fe72011-01-31 16:17:256574 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016575 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296576
bnc691fda62016-08-12 00:43:166577 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416578 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166579 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256581 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016582 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166583 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226584
bnc691fda62016-08-12 00:43:166585 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526586 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046587 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226588
[email protected]49639fa2011-12-20 23:22:416589 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226590
6591 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376592 rv = trans.RestartWithAuth(
6593 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6594 callback4.callback());
robpercival214763f2016-07-01 23:27:016595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256596
6597 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016598 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256599
bnc691fda62016-08-12 00:43:166600 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256601
[email protected]49639fa2011-12-20 23:22:416602 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256603
6604 // One more roundtrip
bnc691fda62016-08-12 00:43:166605 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226607
6608 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016609 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226610
bnc691fda62016-08-12 00:43:166611 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526612 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026613 EXPECT_EQ(14, response->headers->GetContentLength());
6614
6615 std::string response_data;
6616 rv = ReadTransaction(&trans, &response_data);
6617 EXPECT_THAT(rv, IsOk());
6618 EXPECT_EQ("Please Login\r\n", response_data);
6619
6620 EXPECT_TRUE(data1.AllReadDataConsumed());
6621 EXPECT_TRUE(data1.AllWriteDataConsumed());
6622 EXPECT_TRUE(data2.AllReadDataConsumed());
6623 EXPECT_TRUE(data2.AllWriteDataConsumed());
6624 EXPECT_TRUE(data3.AllReadDataConsumed());
6625 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296626}
Bence Béky83eb3512017-09-05 12:56:096627
Bence Béky3238f2e12017-09-22 22:44:496628// Server requests NTLM authentication, which is not supported over HTTP/2.
6629// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096630TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096631 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6632 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096633
Zentaro Kavanagh1890a3d2018-01-29 19:52:556634 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096635
6636 HttpRequestInfo request;
6637 request.method = "GET";
6638 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:106639 request.traffic_annotation =
6640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096641
6642 // First request without credentials.
6643 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6644 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6645 1, std::move(request_headers0), LOWEST, true));
6646
6647 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276648 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096649 response_headers0["www-authenticate"] = "NTLM";
6650 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6651 1, std::move(response_headers0), true));
6652
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376653 // Stream 1 is closed.
6654 spdy_util_.UpdateWithStreamDestruction(1);
6655
6656 // Generate the NTLM messages based on known test data.
6657 std::string negotiate_msg;
6658 std::string challenge_msg;
6659 std::string authenticate_msg;
6660 base::Base64Encode(
6661 base::StringPiece(
6662 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6663 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6664 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556665 base::Base64Encode(
6666 base::StringPiece(
6667 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6668 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6669 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376670 base::Base64Encode(
6671 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096672 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556673 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6674 arraysize(
6675 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376676 &authenticate_msg);
6677
6678 // Retry with authorization header.
6679 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6680 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6681 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6682 3, std::move(request_headers1), LOWEST, true));
6683
6684 SpdySerializedFrame rst(
6685 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6686
Bence Béky3238f2e12017-09-22 22:44:496687 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6688 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096689
6690 // Retry yet again using HTTP/1.1.
6691 MockWrite writes1[] = {
6692 // After restarting with a null identity, this is the
6693 // request we should be issuing -- the final header line contains a Type
6694 // 1 message.
6695 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556696 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096697 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376698 "Authorization: NTLM "),
6699 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096700
6701 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6702 // (the credentials for the origin server). The second request continues
6703 // on the same connection.
6704 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556705 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096706 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376707 "Authorization: NTLM "),
6708 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096709 };
6710
6711 MockRead reads1[] = {
6712 // The origin server responds with a Type 2 message.
6713 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376714 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6715 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096716 MockRead("Content-Type: text/html\r\n\r\n"),
6717 MockRead("You are not authorized to view this page\r\n"),
6718
6719 // Lastly we get the desired content.
6720 MockRead("HTTP/1.1 200 OK\r\n"),
6721 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026722 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096723 };
Ryan Sleevib8d7ea02018-05-07 20:01:016724 SequencedSocketData data0(reads0, writes0);
6725 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:096726 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6727 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6728
6729 SSLSocketDataProvider ssl0(ASYNC, OK);
6730 ssl0.next_proto = kProtoHTTP2;
6731 SSLSocketDataProvider ssl1(ASYNC, OK);
6732 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6733 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6734
6735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6737
6738 TestCompletionCallback callback1;
6739 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6741
6742 rv = callback1.WaitForResult();
6743 EXPECT_THAT(rv, IsOk());
6744
6745 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6746
6747 const HttpResponseInfo* response = trans.GetResponseInfo();
6748 ASSERT_TRUE(response);
6749 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6750
6751 TestCompletionCallback callback2;
6752
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376753 rv = trans.RestartWithAuth(
6754 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6755 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6757
6758 rv = callback2.WaitForResult();
6759 EXPECT_THAT(rv, IsOk());
6760
6761 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6762
6763 response = trans.GetResponseInfo();
6764 ASSERT_TRUE(response);
6765 EXPECT_FALSE(response->auth_challenge);
6766
6767 TestCompletionCallback callback3;
6768
6769 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6771
6772 rv = callback3.WaitForResult();
6773 EXPECT_THAT(rv, IsOk());
6774
6775 response = trans.GetResponseInfo();
6776 ASSERT_TRUE(response);
6777 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026778 EXPECT_EQ(14, response->headers->GetContentLength());
6779
6780 std::string response_data;
6781 rv = ReadTransaction(&trans, &response_data);
6782 EXPECT_THAT(rv, IsOk());
6783 EXPECT_EQ("Please Login\r\n", response_data);
6784
6785 EXPECT_TRUE(data0.AllReadDataConsumed());
6786 EXPECT_TRUE(data0.AllWriteDataConsumed());
6787 EXPECT_TRUE(data1.AllReadDataConsumed());
6788 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096789}
David Benjamin5cb91132018-04-06 05:54:496790
6791// Test that, if we have an NTLM proxy and the origin resets the connection, we
6792// do no retry forever checking for TLS version interference. This is a
6793// regression test for https://crbug.com/823387.
6794TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
6795 // The NTLM test data expects the proxy to be named 'server'. The origin is
6796 // https://origin/.
6797 session_deps_.proxy_resolution_service =
6798 ProxyResolutionService::CreateFixedFromPacResult(
6799 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
6800
6801 SSLConfig config;
6802 config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
6803 session_deps_.ssl_config_service =
6804 base::MakeRefCounted<TestSSLConfigService>(config);
6805
6806 HttpRequestInfo request;
6807 request.method = "GET";
6808 request.url = GURL("https://origin/");
6809 request.traffic_annotation =
6810 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6811
6812 // Ensure load is not disrupted by flags which suppress behaviour specific
6813 // to other auth schemes.
6814 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6815
6816 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6817 MockGetMSTime, MockGenerateRandom, MockGetHostName);
6818 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6819
6820 // Generate the NTLM messages based on known test data.
6821 std::string negotiate_msg;
6822 std::string challenge_msg;
6823 std::string authenticate_msg;
6824 base::Base64Encode(
6825 base::StringPiece(
6826 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6827 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6828 &negotiate_msg);
6829 base::Base64Encode(
6830 base::StringPiece(
6831 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6832 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6833 &challenge_msg);
6834 base::Base64Encode(
6835 base::StringPiece(
6836 reinterpret_cast<const char*>(
6837 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6838 arraysize(
6839 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
6840 &authenticate_msg);
6841
6842 MockWrite data_writes[] = {
6843 // The initial CONNECT request.
6844 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6845 "Host: origin:443\r\n"
6846 "Proxy-Connection: keep-alive\r\n\r\n"),
6847
6848 // After restarting with an identity.
6849 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6850 "Host: origin:443\r\n"
6851 "Proxy-Connection: keep-alive\r\n"
6852 "Proxy-Authorization: NTLM "),
6853 MockWrite(negotiate_msg.c_str()),
6854 // End headers.
6855 MockWrite("\r\n\r\n"),
6856
6857 // The second restart.
6858 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6859 "Host: origin:443\r\n"
6860 "Proxy-Connection: keep-alive\r\n"
6861 "Proxy-Authorization: NTLM "),
6862 MockWrite(authenticate_msg.c_str()),
6863 // End headers.
6864 MockWrite("\r\n\r\n"),
6865 };
6866
6867 MockRead data_reads[] = {
6868 // The initial NTLM response.
6869 MockRead("HTTP/1.1 407 Access Denied\r\n"
6870 "Content-Length: 0\r\n"
6871 "Proxy-Authenticate: NTLM\r\n\r\n"),
6872
6873 // The NTLM challenge message.
6874 MockRead("HTTP/1.1 407 Access Denied\r\n"
6875 "Content-Length: 0\r\n"
6876 "Proxy-Authenticate: NTLM "),
6877 MockRead(challenge_msg.c_str()),
6878 // End headers.
6879 MockRead("\r\n\r\n"),
6880
6881 // Finally the tunnel is established.
6882 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
6883 };
6884
Ryan Sleevib8d7ea02018-05-07 20:01:016885 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496886 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:016887 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496888 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
6889 session_deps_.socket_factory->AddSocketDataProvider(&data);
6890 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
6891 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6892 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
6893
6894 // Start the transaction. The proxy responds with an NTLM authentication
6895 // request.
6896 TestCompletionCallback callback;
6897 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6898 int rv = callback.GetResult(
6899 trans.Start(&request, callback.callback(), NetLogWithSource()));
6900
6901 EXPECT_THAT(rv, IsOk());
6902 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6903 const HttpResponseInfo* response = trans.GetResponseInfo();
6904 ASSERT_TRUE(response);
6905 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
6906
6907 // Configure credentials. The proxy responds with the challenge message.
6908 rv = callback.GetResult(trans.RestartWithAuth(
6909 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6910 callback.callback()));
6911 EXPECT_THAT(rv, IsOk());
6912 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6913 response = trans.GetResponseInfo();
6914 ASSERT_TRUE(response);
6915 EXPECT_FALSE(response->auth_challenge);
6916
6917 // Restart once more. The tunnel will be established and the the SSL handshake
6918 // will reset. The TLS 1.3 version interference probe will then kick in and
6919 // restart the process. The proxy responds with another NTLM authentiation
6920 // request, but we don't need to provide credentials as the cached ones work/
6921 rv = callback.GetResult(
6922 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6923 EXPECT_THAT(rv, IsOk());
6924 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6925 response = trans.GetResponseInfo();
6926 ASSERT_TRUE(response);
6927 EXPECT_FALSE(response->auth_challenge);
6928
6929 // The proxy responds with the NTLM challenge message.
6930 rv = callback.GetResult(
6931 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6932 EXPECT_THAT(rv, IsOk());
6933 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6934 response = trans.GetResponseInfo();
6935 ASSERT_TRUE(response);
6936 EXPECT_FALSE(response->auth_challenge);
6937
6938 // Send the NTLM authenticate message. The tunnel is established and the
6939 // handshake resets again. We should not retry again.
6940 rv = callback.GetResult(
6941 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6942 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
6943}
6944
[email protected]ea9dc9a2009-09-05 00:43:326945#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296946
[email protected]4ddaf2502008-10-23 18:26:196947// Test reading a server response which has only headers, and no body.
6948// After some maximum number of bytes is consumed, the transaction should
6949// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016950TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426951 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196952 request.method = "GET";
bncce36dca22015-04-21 22:11:236953 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106954 request.traffic_annotation =
6955 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196956
danakj1fd259a02016-04-16 03:17:096957 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166958 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276959
[email protected]b75b7b2f2009-10-06 00:54:536960 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436961 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536962 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196963
6964 MockRead data_reads[] = {
6965 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066966 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196967 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066968 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196969 };
Ryan Sleevib8d7ea02018-05-07 20:01:016970 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:076971 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196972
[email protected]49639fa2011-12-20 23:22:416973 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196974
tfarina42834112016-09-22 13:38:206975 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196977
6978 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016979 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196980}
[email protected]f4e426b2008-11-05 00:24:496981
6982// Make sure that we don't try to reuse a TCPClientSocket when failing to
6983// establish tunnel.
6984// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016985TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276986 HttpRequestInfo request;
6987 request.method = "GET";
bncce36dca22015-04-21 22:11:236988 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106989 request.traffic_annotation =
6990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276991
[email protected]f4e426b2008-11-05 00:24:496992 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496993 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6994 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:016995
danakj1fd259a02016-04-16 03:17:096996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496997
bnc87dcefc2017-05-25 12:47:586998 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196999 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497000
[email protected]f4e426b2008-11-05 00:24:497001 // Since we have proxy, should try to establish tunnel.
7002 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177003 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7004 "Host: www.example.org:443\r\n"
7005 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497006 };
7007
[email protected]77848d12008-11-14 00:00:227008 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497009 // connection. Usually a proxy would return 501 (not implemented),
7010 // or 200 (tunnel established).
7011 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237012 MockRead("HTTP/1.1 404 Not Found\r\n"),
7013 MockRead("Content-Length: 10\r\n\r\n"),
7014 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497015 };
7016
Ryan Sleevib8d7ea02018-05-07 20:01:017017 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077018 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497019
[email protected]49639fa2011-12-20 23:22:417020 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497021
tfarina42834112016-09-22 13:38:207022 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497024
7025 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017026 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497027
[email protected]b4404c02009-04-10 16:38:527028 // Empty the current queue. This is necessary because idle sockets are
7029 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557030 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527031
[email protected]f4e426b2008-11-05 00:24:497032 // We now check to make sure the TCPClientSocket was not added back to
7033 // the pool.
[email protected]90499482013-06-01 00:39:507034 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497035 trans.reset();
fdoray92e35a72016-06-10 15:54:557036 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497037 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507038 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497039}
[email protected]372d34a2008-11-05 21:30:517040
[email protected]1b157c02009-04-21 01:55:407041// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017042TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427043 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407044 request.method = "GET";
bncce36dca22015-04-21 22:11:237045 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107046 request.traffic_annotation =
7047 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407048
danakj1fd259a02016-04-16 03:17:097049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277050
bnc691fda62016-08-12 00:43:167051 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277052
[email protected]1b157c02009-04-21 01:55:407053 MockRead data_reads[] = {
7054 // A part of the response body is received with the response headers.
7055 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7056 // The rest of the response body is received in two parts.
7057 MockRead("lo"),
7058 MockRead(" world"),
7059 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067060 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407061 };
7062
Ryan Sleevib8d7ea02018-05-07 20:01:017063 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077064 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407065
[email protected]49639fa2011-12-20 23:22:417066 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407067
tfarina42834112016-09-22 13:38:207068 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407070
7071 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017072 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407073
bnc691fda62016-08-12 00:43:167074 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527075 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407076
wezca1070932016-05-26 20:30:527077 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407078 std::string status_line = response->headers->GetStatusLine();
7079 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7080
[email protected]90499482013-06-01 00:39:507081 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407082
7083 std::string response_data;
bnc691fda62016-08-12 00:43:167084 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017085 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407086 EXPECT_EQ("hello world", response_data);
7087
7088 // Empty the current queue. This is necessary because idle sockets are
7089 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557090 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407091
7092 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507093 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407094}
7095
[email protected]76a505b2010-08-25 06:23:007096// Make sure that we recycle a SSL socket after reading all of the response
7097// body.
bncd16676a2016-07-20 16:23:017098TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007099 HttpRequestInfo request;
7100 request.method = "GET";
bncce36dca22015-04-21 22:11:237101 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107102 request.traffic_annotation =
7103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007104
7105 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237106 MockWrite(
7107 "GET / HTTP/1.1\r\n"
7108 "Host: www.example.org\r\n"
7109 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007110 };
7111
7112 MockRead data_reads[] = {
7113 MockRead("HTTP/1.1 200 OK\r\n"),
7114 MockRead("Content-Length: 11\r\n\r\n"),
7115 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067116 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007117 };
7118
[email protected]8ddf8322012-02-23 18:08:067119 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007121
Ryan Sleevib8d7ea02018-05-07 20:01:017122 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077123 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007124
[email protected]49639fa2011-12-20 23:22:417125 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007126
danakj1fd259a02016-04-16 03:17:097127 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007129
tfarina42834112016-09-22 13:38:207130 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007131
robpercival214763f2016-07-01 23:27:017132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7133 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007134
bnc691fda62016-08-12 00:43:167135 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527136 ASSERT_TRUE(response);
7137 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007138 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7139
[email protected]90499482013-06-01 00:39:507140 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007141
7142 std::string response_data;
bnc691fda62016-08-12 00:43:167143 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017144 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007145 EXPECT_EQ("hello world", response_data);
7146
7147 // Empty the current queue. This is necessary because idle sockets are
7148 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557149 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007150
7151 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507152 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007153}
7154
7155// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7156// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017157TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007158 HttpRequestInfo request;
7159 request.method = "GET";
bncce36dca22015-04-21 22:11:237160 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107161 request.traffic_annotation =
7162 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007163
7164 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237165 MockWrite(
7166 "GET / HTTP/1.1\r\n"
7167 "Host: www.example.org\r\n"
7168 "Connection: keep-alive\r\n\r\n"),
7169 MockWrite(
7170 "GET / HTTP/1.1\r\n"
7171 "Host: www.example.org\r\n"
7172 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007173 };
7174
7175 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427176 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7177 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007178
[email protected]8ddf8322012-02-23 18:08:067179 SSLSocketDataProvider ssl(ASYNC, OK);
7180 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077181 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007183
Ryan Sleevib8d7ea02018-05-07 20:01:017184 StaticSocketDataProvider data(data_reads, data_writes);
7185 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077186 session_deps_.socket_factory->AddSocketDataProvider(&data);
7187 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007188
[email protected]49639fa2011-12-20 23:22:417189 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007190
danakj1fd259a02016-04-16 03:17:097191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587192 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197193 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007194
tfarina42834112016-09-22 13:38:207195 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007196
robpercival214763f2016-07-01 23:27:017197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7198 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007199
7200 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527201 ASSERT_TRUE(response);
7202 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007203 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7204
[email protected]90499482013-06-01 00:39:507205 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007206
7207 std::string response_data;
7208 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017209 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007210 EXPECT_EQ("hello world", response_data);
7211
7212 // Empty the current queue. This is necessary because idle sockets are
7213 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557214 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007215
7216 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507217 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007218
7219 // Now start the second transaction, which should reuse the previous socket.
7220
bnc87dcefc2017-05-25 12:47:587221 trans =
Jeremy Roman0579ed62017-08-29 15:56:197222 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007223
tfarina42834112016-09-22 13:38:207224 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007225
robpercival214763f2016-07-01 23:27:017226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7227 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007228
7229 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527230 ASSERT_TRUE(response);
7231 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007232 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7233
[email protected]90499482013-06-01 00:39:507234 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007235
7236 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017237 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007238 EXPECT_EQ("hello world", response_data);
7239
7240 // Empty the current queue. This is necessary because idle sockets are
7241 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557242 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007243
7244 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507245 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007246}
7247
maksim.sisov0adf8592016-07-15 06:25:567248// Grab a socket, use it, and put it back into the pool. Then, make
7249// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017250TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567251 HttpRequestInfo request;
7252 request.method = "GET";
7253 request.url = GURL("http://www.example.org/");
7254 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107255 request.traffic_annotation =
7256 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567257
7258 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7259
bnc691fda62016-08-12 00:43:167260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567261
7262 MockRead data_reads[] = {
7263 // A part of the response body is received with the response headers.
7264 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7265 // The rest of the response body is received in two parts.
7266 MockRead("lo"), MockRead(" world"),
7267 MockRead("junk"), // Should not be read!!
7268 MockRead(SYNCHRONOUS, OK),
7269 };
7270
Ryan Sleevib8d7ea02018-05-07 20:01:017271 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:567272 session_deps_.socket_factory->AddSocketDataProvider(&data);
7273
7274 TestCompletionCallback callback;
7275
tfarina42834112016-09-22 13:38:207276 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7278
7279 EXPECT_THAT(callback.GetResult(rv), IsOk());
7280
bnc691fda62016-08-12 00:43:167281 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567282 ASSERT_TRUE(response);
7283 EXPECT_TRUE(response->headers);
7284 std::string status_line = response->headers->GetStatusLine();
7285 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7286
7287 // Make memory critical notification and ensure the transaction still has been
7288 // operating right.
7289 base::MemoryPressureListener::NotifyMemoryPressure(
7290 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7291 base::RunLoop().RunUntilIdle();
7292
7293 // Socket should not be flushed as long as it is not idle.
7294 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7295
7296 std::string response_data;
bnc691fda62016-08-12 00:43:167297 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567298 EXPECT_THAT(rv, IsOk());
7299 EXPECT_EQ("hello world", response_data);
7300
7301 // Empty the current queue. This is necessary because idle sockets are
7302 // added to the connection pool asynchronously with a PostTask.
7303 base::RunLoop().RunUntilIdle();
7304
7305 // We now check to make sure the socket was added back to the pool.
7306 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7307
7308 // Idle sockets should be flushed now.
7309 base::MemoryPressureListener::NotifyMemoryPressure(
7310 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7311 base::RunLoop().RunUntilIdle();
7312
7313 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7314}
7315
yucliu48f235d2018-01-11 00:59:557316// Disable idle socket closing on memory pressure.
7317// Grab a socket, use it, and put it back into the pool. Then, make
7318// low memory notification and ensure the socket pool is NOT flushed.
7319TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7320 HttpRequestInfo request;
7321 request.method = "GET";
7322 request.url = GURL("http://www.example.org/");
7323 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107324 request.traffic_annotation =
7325 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557326
7327 // Disable idle socket closing on memory pressure.
7328 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7330
7331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7332
7333 MockRead data_reads[] = {
7334 // A part of the response body is received with the response headers.
7335 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7336 // The rest of the response body is received in two parts.
7337 MockRead("lo"), MockRead(" world"),
7338 MockRead("junk"), // Should not be read!!
7339 MockRead(SYNCHRONOUS, OK),
7340 };
7341
Ryan Sleevib8d7ea02018-05-07 20:01:017342 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:557343 session_deps_.socket_factory->AddSocketDataProvider(&data);
7344
7345 TestCompletionCallback callback;
7346
7347 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7349
7350 EXPECT_THAT(callback.GetResult(rv), IsOk());
7351
7352 const HttpResponseInfo* response = trans.GetResponseInfo();
7353 ASSERT_TRUE(response);
7354 EXPECT_TRUE(response->headers);
7355 std::string status_line = response->headers->GetStatusLine();
7356 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7357
7358 // Make memory critical notification and ensure the transaction still has been
7359 // operating right.
7360 base::MemoryPressureListener::NotifyMemoryPressure(
7361 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7362 base::RunLoop().RunUntilIdle();
7363
7364 // Socket should not be flushed as long as it is not idle.
7365 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7366
7367 std::string response_data;
7368 rv = ReadTransaction(&trans, &response_data);
7369 EXPECT_THAT(rv, IsOk());
7370 EXPECT_EQ("hello world", response_data);
7371
7372 // Empty the current queue. This is necessary because idle sockets are
7373 // added to the connection pool asynchronously with a PostTask.
7374 base::RunLoop().RunUntilIdle();
7375
7376 // We now check to make sure the socket was added back to the pool.
7377 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7378
7379 // Idle sockets should NOT be flushed on moderate memory pressure.
7380 base::MemoryPressureListener::NotifyMemoryPressure(
7381 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7382 base::RunLoop().RunUntilIdle();
7383
7384 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7385
7386 // Idle sockets should NOT be flushed on critical memory pressure.
7387 base::MemoryPressureListener::NotifyMemoryPressure(
7388 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7389 base::RunLoop().RunUntilIdle();
7390
7391 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7392}
7393
maksim.sisov0adf8592016-07-15 06:25:567394// Grab an SSL socket, use it, and put it back into the pool. Then, make
7395// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017396TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567397 HttpRequestInfo request;
7398 request.method = "GET";
7399 request.url = GURL("https://www.example.org/");
7400 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107401 request.traffic_annotation =
7402 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567403
7404 MockWrite data_writes[] = {
7405 MockWrite("GET / HTTP/1.1\r\n"
7406 "Host: www.example.org\r\n"
7407 "Connection: keep-alive\r\n\r\n"),
7408 };
7409
7410 MockRead data_reads[] = {
7411 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7412 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7413
7414 SSLSocketDataProvider ssl(ASYNC, OK);
7415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7416
Ryan Sleevib8d7ea02018-05-07 20:01:017417 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:567418 session_deps_.socket_factory->AddSocketDataProvider(&data);
7419
7420 TestCompletionCallback callback;
7421
7422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567424
7425 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207426 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567427
7428 EXPECT_THAT(callback.GetResult(rv), IsOk());
7429
bnc691fda62016-08-12 00:43:167430 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567431 ASSERT_TRUE(response);
7432 ASSERT_TRUE(response->headers);
7433 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7434
7435 // Make memory critical notification and ensure the transaction still has been
7436 // operating right.
7437 base::MemoryPressureListener::NotifyMemoryPressure(
7438 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7439 base::RunLoop().RunUntilIdle();
7440
7441 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7442
7443 std::string response_data;
bnc691fda62016-08-12 00:43:167444 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567445 EXPECT_THAT(rv, IsOk());
7446 EXPECT_EQ("hello world", response_data);
7447
7448 // Empty the current queue. This is necessary because idle sockets are
7449 // added to the connection pool asynchronously with a PostTask.
7450 base::RunLoop().RunUntilIdle();
7451
7452 // We now check to make sure the socket was added back to the pool.
7453 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7454
7455 // Make memory notification once again and ensure idle socket is closed.
7456 base::MemoryPressureListener::NotifyMemoryPressure(
7457 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7458 base::RunLoop().RunUntilIdle();
7459
7460 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7461}
7462
[email protected]b4404c02009-04-10 16:38:527463// Make sure that we recycle a socket after a zero-length response.
7464// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017465TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427466 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527467 request.method = "GET";
bncce36dca22015-04-21 22:11:237468 request.url = GURL(
7469 "http://www.example.org/csi?v=3&s=web&action=&"
7470 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7471 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7472 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:107473 request.traffic_annotation =
7474 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527475
danakj1fd259a02016-04-16 03:17:097476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277477
[email protected]b4404c02009-04-10 16:38:527478 MockRead data_reads[] = {
7479 MockRead("HTTP/1.1 204 No Content\r\n"
7480 "Content-Length: 0\r\n"
7481 "Content-Type: text/html\r\n\r\n"),
7482 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067483 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527484 };
7485
Ryan Sleevib8d7ea02018-05-07 20:01:017486 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077487 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527488
mmenkecc2298e2015-12-07 18:20:187489 // Transaction must be created after the MockReads, so it's destroyed before
7490 // them.
bnc691fda62016-08-12 00:43:167491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187492
[email protected]49639fa2011-12-20 23:22:417493 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527494
tfarina42834112016-09-22 13:38:207495 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017496 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527497
7498 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017499 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527500
bnc691fda62016-08-12 00:43:167501 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527502 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527503
wezca1070932016-05-26 20:30:527504 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527505 std::string status_line = response->headers->GetStatusLine();
7506 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7507
[email protected]90499482013-06-01 00:39:507508 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527509
7510 std::string response_data;
bnc691fda62016-08-12 00:43:167511 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017512 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527513 EXPECT_EQ("", response_data);
7514
7515 // Empty the current queue. This is necessary because idle sockets are
7516 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557517 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527518
7519 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507520 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527521}
7522
bncd16676a2016-07-20 16:23:017523TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097524 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227525 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197526 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227527 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277528
[email protected]1c773ea12009-04-28 19:58:427529 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517530 // Transaction 1: a GET request that succeeds. The socket is recycled
7531 // after use.
7532 request[0].method = "GET";
7533 request[0].url = GURL("http://www.google.com/");
7534 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107535 request[0].traffic_annotation =
7536 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517537 // Transaction 2: a POST request. Reuses the socket kept alive from
7538 // transaction 1. The first attempts fails when writing the POST data.
7539 // This causes the transaction to retry with a new socket. The second
7540 // attempt succeeds.
7541 request[1].method = "POST";
7542 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277543 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517544 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107545 request[1].traffic_annotation =
7546 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517547
danakj1fd259a02016-04-16 03:17:097548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517549
7550 // The first socket is used for transaction 1 and the first attempt of
7551 // transaction 2.
7552
7553 // The response of transaction 1.
7554 MockRead data_reads1[] = {
7555 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7556 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067557 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517558 };
7559 // The mock write results of transaction 1 and the first attempt of
7560 // transaction 2.
7561 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067562 MockWrite(SYNCHRONOUS, 64), // GET
7563 MockWrite(SYNCHRONOUS, 93), // POST
7564 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517565 };
Ryan Sleevib8d7ea02018-05-07 20:01:017566 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:517567
7568 // The second socket is used for the second attempt of transaction 2.
7569
7570 // The response of transaction 2.
7571 MockRead data_reads2[] = {
7572 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7573 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067574 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517575 };
7576 // The mock write results of the second attempt of transaction 2.
7577 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067578 MockWrite(SYNCHRONOUS, 93), // POST
7579 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517580 };
Ryan Sleevib8d7ea02018-05-07 20:01:017581 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:517582
[email protected]bb88e1d32013-05-03 23:11:077583 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7584 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517585
thestig9d3bb0c2015-01-24 00:49:517586 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517587 "hello world", "welcome"
7588 };
7589
7590 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517592
[email protected]49639fa2011-12-20 23:22:417593 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517594
tfarina42834112016-09-22 13:38:207595 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517597
7598 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017599 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517600
bnc691fda62016-08-12 00:43:167601 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527602 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517603
wezca1070932016-05-26 20:30:527604 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7606
7607 std::string response_data;
bnc691fda62016-08-12 00:43:167608 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017609 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517610 EXPECT_EQ(kExpectedResponseData[i], response_data);
7611 }
7612}
[email protected]f9ee6b52008-11-08 06:46:237613
7614// Test the request-challenge-retry sequence for basic auth when there is
7615// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167616// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017617TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427618 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237619 request.method = "GET";
bncce36dca22015-04-21 22:11:237620 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417621 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107622 request.traffic_annotation =
7623 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297624
danakj1fd259a02016-04-16 03:17:097625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277627
[email protected]a97cca42009-08-14 01:00:297628 // The password contains an escaped character -- for this test to pass it
7629 // will need to be unescaped by HttpNetworkTransaction.
7630 EXPECT_EQ("b%40r", request.url.password());
7631
[email protected]f9ee6b52008-11-08 06:46:237632 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237633 MockWrite(
7634 "GET / HTTP/1.1\r\n"
7635 "Host: www.example.org\r\n"
7636 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237637 };
7638
7639 MockRead data_reads1[] = {
7640 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7641 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7642 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067643 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237644 };
7645
[email protected]2262e3a2012-05-22 16:08:167646 // After the challenge above, the transaction will be restarted using the
7647 // identity from the url (foo, b@r) to answer the challenge.
7648 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237649 MockWrite(
7650 "GET / HTTP/1.1\r\n"
7651 "Host: www.example.org\r\n"
7652 "Connection: keep-alive\r\n"
7653 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167654 };
7655
7656 MockRead data_reads2[] = {
7657 MockRead("HTTP/1.0 200 OK\r\n"),
7658 MockRead("Content-Length: 100\r\n\r\n"),
7659 MockRead(SYNCHRONOUS, OK),
7660 };
7661
Ryan Sleevib8d7ea02018-05-07 20:01:017662 StaticSocketDataProvider data1(data_reads1, data_writes1);
7663 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7665 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237666
[email protected]49639fa2011-12-20 23:22:417667 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207668 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237670 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017671 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167672 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167673
7674 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167675 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167677 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017678 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167679 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227680
bnc691fda62016-08-12 00:43:167681 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527682 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167683
7684 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527685 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167686
7687 EXPECT_EQ(100, response->headers->GetContentLength());
7688
7689 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557690 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167691}
7692
7693// Test the request-challenge-retry sequence for basic auth when there is an
7694// incorrect identity in the URL. The identity from the URL should be used only
7695// once.
bncd16676a2016-07-20 16:23:017696TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167697 HttpRequestInfo request;
7698 request.method = "GET";
7699 // Note: the URL has a username:password in it. The password "baz" is
7700 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237701 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167702
7703 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107704 request.traffic_annotation =
7705 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167706
danakj1fd259a02016-04-16 03:17:097707 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167709
7710 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237711 MockWrite(
7712 "GET / HTTP/1.1\r\n"
7713 "Host: www.example.org\r\n"
7714 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167715 };
7716
7717 MockRead data_reads1[] = {
7718 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7719 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7720 MockRead("Content-Length: 10\r\n\r\n"),
7721 MockRead(SYNCHRONOUS, ERR_FAILED),
7722 };
7723
7724 // After the challenge above, the transaction will be restarted using the
7725 // identity from the url (foo, baz) to answer the challenge.
7726 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237727 MockWrite(
7728 "GET / HTTP/1.1\r\n"
7729 "Host: www.example.org\r\n"
7730 "Connection: keep-alive\r\n"
7731 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167732 };
7733
7734 MockRead data_reads2[] = {
7735 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7736 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7737 MockRead("Content-Length: 10\r\n\r\n"),
7738 MockRead(SYNCHRONOUS, ERR_FAILED),
7739 };
7740
7741 // After the challenge above, the transaction will be restarted using the
7742 // identity supplied by the user (foo, bar) to answer the challenge.
7743 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237744 MockWrite(
7745 "GET / HTTP/1.1\r\n"
7746 "Host: www.example.org\r\n"
7747 "Connection: keep-alive\r\n"
7748 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167749 };
7750
7751 MockRead data_reads3[] = {
7752 MockRead("HTTP/1.0 200 OK\r\n"),
7753 MockRead("Content-Length: 100\r\n\r\n"),
7754 MockRead(SYNCHRONOUS, OK),
7755 };
7756
Ryan Sleevib8d7ea02018-05-07 20:01:017757 StaticSocketDataProvider data1(data_reads1, data_writes1);
7758 StaticSocketDataProvider data2(data_reads2, data_writes2);
7759 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077760 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7761 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7762 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167763
7764 TestCompletionCallback callback1;
7765
tfarina42834112016-09-22 13:38:207766 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167768
7769 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017770 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167771
bnc691fda62016-08-12 00:43:167772 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167773 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167774 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017775 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167776 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017777 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167778 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167779
bnc691fda62016-08-12 00:43:167780 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527781 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167782 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7783
7784 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167785 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167787 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017788 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167789 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167790
bnc691fda62016-08-12 00:43:167791 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527792 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167793
7794 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527795 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167796
7797 EXPECT_EQ(100, response->headers->GetContentLength());
7798
[email protected]ea9dc9a2009-09-05 00:43:327799 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557800 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327801}
7802
[email protected]2217aa22013-10-11 03:03:547803
7804// Test the request-challenge-retry sequence for basic auth when there is a
7805// correct identity in the URL, but its use is being suppressed. The identity
7806// from the URL should never be used.
bncd16676a2016-07-20 16:23:017807TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547808 HttpRequestInfo request;
7809 request.method = "GET";
bncce36dca22015-04-21 22:11:237810 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547811 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:107812 request.traffic_annotation =
7813 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547814
danakj1fd259a02016-04-16 03:17:097815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547817
7818 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237819 MockWrite(
7820 "GET / HTTP/1.1\r\n"
7821 "Host: www.example.org\r\n"
7822 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547823 };
7824
7825 MockRead data_reads1[] = {
7826 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7827 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7828 MockRead("Content-Length: 10\r\n\r\n"),
7829 MockRead(SYNCHRONOUS, ERR_FAILED),
7830 };
7831
7832 // After the challenge above, the transaction will be restarted using the
7833 // identity supplied by the user, not the one in the URL, to answer the
7834 // challenge.
7835 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237836 MockWrite(
7837 "GET / HTTP/1.1\r\n"
7838 "Host: www.example.org\r\n"
7839 "Connection: keep-alive\r\n"
7840 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547841 };
7842
7843 MockRead data_reads3[] = {
7844 MockRead("HTTP/1.0 200 OK\r\n"),
7845 MockRead("Content-Length: 100\r\n\r\n"),
7846 MockRead(SYNCHRONOUS, OK),
7847 };
7848
Ryan Sleevib8d7ea02018-05-07 20:01:017849 StaticSocketDataProvider data1(data_reads1, data_writes1);
7850 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:547851 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7852 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7853
7854 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207855 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547857 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017858 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167859 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547860
bnc691fda62016-08-12 00:43:167861 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527862 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547863 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7864
7865 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167866 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547868 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017869 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167870 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547871
bnc691fda62016-08-12 00:43:167872 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527873 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547874
7875 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527876 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547877 EXPECT_EQ(100, response->headers->GetContentLength());
7878
7879 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557880 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547881}
7882
[email protected]f9ee6b52008-11-08 06:46:237883// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017884TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237886
7887 // Transaction 1: authenticate (foo, bar) on MyRealm1
7888 {
[email protected]1c773ea12009-04-28 19:58:427889 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237890 request.method = "GET";
bncce36dca22015-04-21 22:11:237891 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:107892 request.traffic_annotation =
7893 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237894
bnc691fda62016-08-12 00:43:167895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277896
[email protected]f9ee6b52008-11-08 06:46:237897 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237898 MockWrite(
7899 "GET /x/y/z HTTP/1.1\r\n"
7900 "Host: www.example.org\r\n"
7901 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237902 };
7903
7904 MockRead data_reads1[] = {
7905 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7906 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7907 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067908 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237909 };
7910
7911 // Resend with authorization (username=foo, password=bar)
7912 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237913 MockWrite(
7914 "GET /x/y/z HTTP/1.1\r\n"
7915 "Host: www.example.org\r\n"
7916 "Connection: keep-alive\r\n"
7917 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237918 };
7919
7920 // Sever accepts the authorization.
7921 MockRead data_reads2[] = {
7922 MockRead("HTTP/1.0 200 OK\r\n"),
7923 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067924 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237925 };
7926
Ryan Sleevib8d7ea02018-05-07 20:01:017927 StaticSocketDataProvider data1(data_reads1, data_writes1);
7928 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077929 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7930 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237931
[email protected]49639fa2011-12-20 23:22:417932 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237933
tfarina42834112016-09-22 13:38:207934 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017935 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237936
7937 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017938 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237939
bnc691fda62016-08-12 00:43:167940 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527941 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047942 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237943
[email protected]49639fa2011-12-20 23:22:417944 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237945
bnc691fda62016-08-12 00:43:167946 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7947 callback2.callback());
robpercival214763f2016-07-01 23:27:017948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237949
7950 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017951 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237952
bnc691fda62016-08-12 00:43:167953 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527954 ASSERT_TRUE(response);
7955 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237956 EXPECT_EQ(100, response->headers->GetContentLength());
7957 }
7958
7959 // ------------------------------------------------------------------------
7960
7961 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7962 {
[email protected]1c773ea12009-04-28 19:58:427963 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237964 request.method = "GET";
7965 // Note that Transaction 1 was at /x/y/z, so this is in the same
7966 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237967 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:107968 request.traffic_annotation =
7969 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237970
bnc691fda62016-08-12 00:43:167971 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277972
[email protected]f9ee6b52008-11-08 06:46:237973 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237974 MockWrite(
7975 "GET /x/y/a/b HTTP/1.1\r\n"
7976 "Host: www.example.org\r\n"
7977 "Connection: keep-alive\r\n"
7978 // Send preemptive authorization for MyRealm1
7979 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237980 };
7981
7982 // The server didn't like the preemptive authorization, and
7983 // challenges us for a different realm (MyRealm2).
7984 MockRead data_reads1[] = {
7985 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7986 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7987 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067988 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237989 };
7990
7991 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7992 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237993 MockWrite(
7994 "GET /x/y/a/b HTTP/1.1\r\n"
7995 "Host: www.example.org\r\n"
7996 "Connection: keep-alive\r\n"
7997 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237998 };
7999
8000 // Sever accepts the authorization.
8001 MockRead data_reads2[] = {
8002 MockRead("HTTP/1.0 200 OK\r\n"),
8003 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068004 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238005 };
8006
Ryan Sleevib8d7ea02018-05-07 20:01:018007 StaticSocketDataProvider data1(data_reads1, data_writes1);
8008 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078009 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8010 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238011
[email protected]49639fa2011-12-20 23:22:418012 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238013
tfarina42834112016-09-22 13:38:208014 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238016
8017 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018018 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238019
bnc691fda62016-08-12 00:43:168020 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528021 ASSERT_TRUE(response);
8022 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048023 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438024 EXPECT_EQ("http://www.example.org",
8025 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048026 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198027 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238028
[email protected]49639fa2011-12-20 23:22:418029 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238030
bnc691fda62016-08-12 00:43:168031 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8032 callback2.callback());
robpercival214763f2016-07-01 23:27:018033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238034
8035 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018036 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238037
bnc691fda62016-08-12 00:43:168038 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528039 ASSERT_TRUE(response);
8040 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238041 EXPECT_EQ(100, response->headers->GetContentLength());
8042 }
8043
8044 // ------------------------------------------------------------------------
8045
8046 // Transaction 3: Resend a request in MyRealm's protection space --
8047 // succeed with preemptive authorization.
8048 {
[email protected]1c773ea12009-04-28 19:58:428049 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238050 request.method = "GET";
bncce36dca22015-04-21 22:11:238051 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108052 request.traffic_annotation =
8053 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238054
bnc691fda62016-08-12 00:43:168055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278056
[email protected]f9ee6b52008-11-08 06:46:238057 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238058 MockWrite(
8059 "GET /x/y/z2 HTTP/1.1\r\n"
8060 "Host: www.example.org\r\n"
8061 "Connection: keep-alive\r\n"
8062 // The authorization for MyRealm1 gets sent preemptively
8063 // (since the url is in the same protection space)
8064 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238065 };
8066
8067 // Sever accepts the preemptive authorization
8068 MockRead data_reads1[] = {
8069 MockRead("HTTP/1.0 200 OK\r\n"),
8070 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068071 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238072 };
8073
Ryan Sleevib8d7ea02018-05-07 20:01:018074 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078075 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238076
[email protected]49639fa2011-12-20 23:22:418077 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238078
tfarina42834112016-09-22 13:38:208079 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238081
8082 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018083 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238084
bnc691fda62016-08-12 00:43:168085 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528086 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238087
wezca1070932016-05-26 20:30:528088 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238089 EXPECT_EQ(100, response->headers->GetContentLength());
8090 }
8091
8092 // ------------------------------------------------------------------------
8093
8094 // Transaction 4: request another URL in MyRealm (however the
8095 // url is not known to belong to the protection space, so no pre-auth).
8096 {
[email protected]1c773ea12009-04-28 19:58:428097 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238098 request.method = "GET";
bncce36dca22015-04-21 22:11:238099 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108100 request.traffic_annotation =
8101 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238102
bnc691fda62016-08-12 00:43:168103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278104
[email protected]f9ee6b52008-11-08 06:46:238105 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238106 MockWrite(
8107 "GET /x/1 HTTP/1.1\r\n"
8108 "Host: www.example.org\r\n"
8109 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238110 };
8111
8112 MockRead data_reads1[] = {
8113 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8114 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8115 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068116 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238117 };
8118
8119 // Resend with authorization from MyRealm's cache.
8120 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238121 MockWrite(
8122 "GET /x/1 HTTP/1.1\r\n"
8123 "Host: www.example.org\r\n"
8124 "Connection: keep-alive\r\n"
8125 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238126 };
8127
8128 // Sever accepts the authorization.
8129 MockRead data_reads2[] = {
8130 MockRead("HTTP/1.0 200 OK\r\n"),
8131 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068132 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238133 };
8134
Ryan Sleevib8d7ea02018-05-07 20:01:018135 StaticSocketDataProvider data1(data_reads1, data_writes1);
8136 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078137 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8138 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238139
[email protected]49639fa2011-12-20 23:22:418140 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238141
tfarina42834112016-09-22 13:38:208142 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018143 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238144
8145 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018146 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238147
bnc691fda62016-08-12 00:43:168148 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418149 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168150 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018151 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228152 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018153 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168154 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228155
bnc691fda62016-08-12 00:43:168156 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528157 ASSERT_TRUE(response);
8158 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238159 EXPECT_EQ(100, response->headers->GetContentLength());
8160 }
8161
8162 // ------------------------------------------------------------------------
8163
8164 // Transaction 5: request a URL in MyRealm, but the server rejects the
8165 // cached identity. Should invalidate and re-prompt.
8166 {
[email protected]1c773ea12009-04-28 19:58:428167 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238168 request.method = "GET";
bncce36dca22015-04-21 22:11:238169 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:108170 request.traffic_annotation =
8171 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238172
bnc691fda62016-08-12 00:43:168173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278174
[email protected]f9ee6b52008-11-08 06:46:238175 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238176 MockWrite(
8177 "GET /p/q/t HTTP/1.1\r\n"
8178 "Host: www.example.org\r\n"
8179 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238180 };
8181
8182 MockRead data_reads1[] = {
8183 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8184 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8185 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068186 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238187 };
8188
8189 // Resend with authorization from cache for MyRealm.
8190 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238191 MockWrite(
8192 "GET /p/q/t HTTP/1.1\r\n"
8193 "Host: www.example.org\r\n"
8194 "Connection: keep-alive\r\n"
8195 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238196 };
8197
8198 // Sever rejects the authorization.
8199 MockRead data_reads2[] = {
8200 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8201 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8202 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068203 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238204 };
8205
8206 // At this point we should prompt for new credentials for MyRealm.
8207 // Restart with username=foo3, password=foo4.
8208 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238209 MockWrite(
8210 "GET /p/q/t HTTP/1.1\r\n"
8211 "Host: www.example.org\r\n"
8212 "Connection: keep-alive\r\n"
8213 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238214 };
8215
8216 // Sever accepts the authorization.
8217 MockRead data_reads3[] = {
8218 MockRead("HTTP/1.0 200 OK\r\n"),
8219 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068220 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238221 };
8222
Ryan Sleevib8d7ea02018-05-07 20:01:018223 StaticSocketDataProvider data1(data_reads1, data_writes1);
8224 StaticSocketDataProvider data2(data_reads2, data_writes2);
8225 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078226 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8227 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8228 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238229
[email protected]49639fa2011-12-20 23:22:418230 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238231
tfarina42834112016-09-22 13:38:208232 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238234
8235 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018236 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238237
bnc691fda62016-08-12 00:43:168238 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418239 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168240 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228242 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018243 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168244 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228245
bnc691fda62016-08-12 00:43:168246 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528247 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048248 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238249
[email protected]49639fa2011-12-20 23:22:418250 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238251
bnc691fda62016-08-12 00:43:168252 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8253 callback3.callback());
robpercival214763f2016-07-01 23:27:018254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238255
[email protected]0757e7702009-03-27 04:00:228256 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018257 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238258
bnc691fda62016-08-12 00:43:168259 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528260 ASSERT_TRUE(response);
8261 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238262 EXPECT_EQ(100, response->headers->GetContentLength());
8263 }
8264}
[email protected]89ceba9a2009-03-21 03:46:068265
[email protected]3c32c5f2010-05-18 15:18:128266// Tests that nonce count increments when multiple auth attempts
8267// are started with the same nonce.
bncd16676a2016-07-20 16:23:018268TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448269 HttpAuthHandlerDigest::Factory* digest_factory =
8270 new HttpAuthHandlerDigest::Factory();
8271 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8272 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8273 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078274 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098275 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128276
8277 // Transaction 1: authenticate (foo, bar) on MyRealm1
8278 {
[email protected]3c32c5f2010-05-18 15:18:128279 HttpRequestInfo request;
8280 request.method = "GET";
bncce36dca22015-04-21 22:11:238281 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108282 request.traffic_annotation =
8283 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128284
bnc691fda62016-08-12 00:43:168285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278286
[email protected]3c32c5f2010-05-18 15:18:128287 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238288 MockWrite(
8289 "GET /x/y/z HTTP/1.1\r\n"
8290 "Host: www.example.org\r\n"
8291 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128292 };
8293
8294 MockRead data_reads1[] = {
8295 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8296 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8297 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068298 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128299 };
8300
8301 // Resend with authorization (username=foo, password=bar)
8302 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238303 MockWrite(
8304 "GET /x/y/z HTTP/1.1\r\n"
8305 "Host: www.example.org\r\n"
8306 "Connection: keep-alive\r\n"
8307 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8308 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8309 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8310 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128311 };
8312
8313 // Sever accepts the authorization.
8314 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088315 MockRead("HTTP/1.0 200 OK\r\n"),
8316 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128317 };
8318
Ryan Sleevib8d7ea02018-05-07 20:01:018319 StaticSocketDataProvider data1(data_reads1, data_writes1);
8320 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078321 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8322 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128323
[email protected]49639fa2011-12-20 23:22:418324 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128325
tfarina42834112016-09-22 13:38:208326 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018327 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128328
8329 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018330 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128331
bnc691fda62016-08-12 00:43:168332 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528333 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048334 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128335
[email protected]49639fa2011-12-20 23:22:418336 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128337
bnc691fda62016-08-12 00:43:168338 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8339 callback2.callback());
robpercival214763f2016-07-01 23:27:018340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128341
8342 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018343 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128344
bnc691fda62016-08-12 00:43:168345 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528346 ASSERT_TRUE(response);
8347 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128348 }
8349
8350 // ------------------------------------------------------------------------
8351
8352 // Transaction 2: Request another resource in digestive's protection space.
8353 // This will preemptively add an Authorization header which should have an
8354 // "nc" value of 2 (as compared to 1 in the first use.
8355 {
[email protected]3c32c5f2010-05-18 15:18:128356 HttpRequestInfo request;
8357 request.method = "GET";
8358 // Note that Transaction 1 was at /x/y/z, so this is in the same
8359 // protection space as digest.
bncce36dca22015-04-21 22:11:238360 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108361 request.traffic_annotation =
8362 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128363
bnc691fda62016-08-12 00:43:168364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278365
[email protected]3c32c5f2010-05-18 15:18:128366 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238367 MockWrite(
8368 "GET /x/y/a/b HTTP/1.1\r\n"
8369 "Host: www.example.org\r\n"
8370 "Connection: keep-alive\r\n"
8371 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8372 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8373 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8374 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128375 };
8376
8377 // Sever accepts the authorization.
8378 MockRead data_reads1[] = {
8379 MockRead("HTTP/1.0 200 OK\r\n"),
8380 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068381 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128382 };
8383
Ryan Sleevib8d7ea02018-05-07 20:01:018384 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078385 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128386
[email protected]49639fa2011-12-20 23:22:418387 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128388
tfarina42834112016-09-22 13:38:208389 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128391
8392 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018393 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128394
bnc691fda62016-08-12 00:43:168395 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528396 ASSERT_TRUE(response);
8397 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128398 }
8399}
8400
[email protected]89ceba9a2009-03-21 03:46:068401// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018402TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068403 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098404 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168405 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068406
8407 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168408 trans.read_buf_ = new IOBuffer(15);
8409 trans.read_buf_len_ = 15;
8410 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068411
8412 // Setup state in response_
bnc691fda62016-08-12 00:43:168413 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578414 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088415 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578416 response->response_time = base::Time::Now();
8417 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068418
8419 { // Setup state for response_.vary_data
8420 HttpRequestInfo request;
8421 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8422 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278423 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438424 request.extra_headers.SetHeader("Foo", "1");
8425 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508426 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068427 }
8428
8429 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168430 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068431
8432 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168433 EXPECT_FALSE(trans.read_buf_);
8434 EXPECT_EQ(0, trans.read_buf_len_);
8435 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528436 EXPECT_FALSE(response->auth_challenge);
8437 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048438 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088439 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578440 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068441}
8442
[email protected]bacff652009-03-31 17:50:338443// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018444TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338445 HttpRequestInfo request;
8446 request.method = "GET";
bncce36dca22015-04-21 22:11:238447 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108448 request.traffic_annotation =
8449 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338450
danakj1fd259a02016-04-16 03:17:098451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168452 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278453
[email protected]bacff652009-03-31 17:50:338454 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238455 MockWrite(
8456 "GET / HTTP/1.1\r\n"
8457 "Host: www.example.org\r\n"
8458 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338459 };
8460
8461 MockRead data_reads[] = {
8462 MockRead("HTTP/1.0 200 OK\r\n"),
8463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8464 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068465 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338466 };
8467
[email protected]5ecc992a42009-11-11 01:41:598468 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:018469 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068470 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8471 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338472
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8474 session_deps_.socket_factory->AddSocketDataProvider(&data);
8475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338477
[email protected]49639fa2011-12-20 23:22:418478 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338479
tfarina42834112016-09-22 13:38:208480 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338482
8483 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018484 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338485
bnc691fda62016-08-12 00:43:168486 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338488
8489 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018490 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338491
bnc691fda62016-08-12 00:43:168492 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338493
wezca1070932016-05-26 20:30:528494 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338495 EXPECT_EQ(100, response->headers->GetContentLength());
8496}
8497
8498// Test HTTPS connections to a site with a bad certificate, going through a
8499// proxy
bncd16676a2016-07-20 16:23:018500TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498501 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8502 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338503
8504 HttpRequestInfo request;
8505 request.method = "GET";
bncce36dca22015-04-21 22:11:238506 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108507 request.traffic_annotation =
8508 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338509
8510 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178511 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8512 "Host: www.example.org:443\r\n"
8513 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338514 };
8515
8516 MockRead proxy_reads[] = {
8517 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068518 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338519 };
8520
8521 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178522 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8523 "Host: www.example.org:443\r\n"
8524 "Proxy-Connection: keep-alive\r\n\r\n"),
8525 MockWrite("GET / HTTP/1.1\r\n"
8526 "Host: www.example.org\r\n"
8527 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338528 };
8529
8530 MockRead data_reads[] = {
8531 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8532 MockRead("HTTP/1.0 200 OK\r\n"),
8533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8534 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068535 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338536 };
8537
Ryan Sleevib8d7ea02018-05-07 20:01:018538 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
8539 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068540 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8541 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338542
[email protected]bb88e1d32013-05-03 23:11:078543 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8544 session_deps_.socket_factory->AddSocketDataProvider(&data);
8545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338547
[email protected]49639fa2011-12-20 23:22:418548 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338549
8550 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078551 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338552
danakj1fd259a02016-04-16 03:17:098553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338555
tfarina42834112016-09-22 13:38:208556 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338558
8559 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018560 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338561
bnc691fda62016-08-12 00:43:168562 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338564
8565 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018566 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338567
bnc691fda62016-08-12 00:43:168568 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338569
wezca1070932016-05-26 20:30:528570 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338571 EXPECT_EQ(100, response->headers->GetContentLength());
8572 }
8573}
8574
[email protected]2df19bb2010-08-25 20:13:468575
8576// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018577TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598578 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498579 ProxyResolutionService::CreateFixedFromPacResult(
8580 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518581 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078582 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468583
8584 HttpRequestInfo request;
8585 request.method = "GET";
bncce36dca22015-04-21 22:11:238586 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108587 request.traffic_annotation =
8588 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468589
8590 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178591 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8592 "Host: www.example.org:443\r\n"
8593 "Proxy-Connection: keep-alive\r\n\r\n"),
8594 MockWrite("GET / HTTP/1.1\r\n"
8595 "Host: www.example.org\r\n"
8596 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468597 };
8598
8599 MockRead data_reads[] = {
8600 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8601 MockRead("HTTP/1.1 200 OK\r\n"),
8602 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8603 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068604 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468605 };
8606
Ryan Sleevib8d7ea02018-05-07 20:01:018607 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068608 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8609 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468610
[email protected]bb88e1d32013-05-03 23:11:078611 session_deps_.socket_factory->AddSocketDataProvider(&data);
8612 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8613 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468614
[email protected]49639fa2011-12-20 23:22:418615 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468616
danakj1fd259a02016-04-16 03:17:098617 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168618 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468619
tfarina42834112016-09-22 13:38:208620 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468622
8623 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018624 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168625 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468626
wezca1070932016-05-26 20:30:528627 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468628
tbansal2ecbbc72016-10-06 17:15:478629 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468630 EXPECT_TRUE(response->headers->IsKeepAlive());
8631 EXPECT_EQ(200, response->headers->response_code());
8632 EXPECT_EQ(100, response->headers->GetContentLength());
8633 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208634
8635 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168636 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208637 TestLoadTimingNotReusedWithPac(load_timing_info,
8638 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468639}
8640
[email protected]511f6f52010-12-17 03:58:298641// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018642TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598643 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498644 ProxyResolutionService::CreateFixedFromPacResult(
8645 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518646 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078647 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298648
8649 HttpRequestInfo request;
8650 request.method = "GET";
bncce36dca22015-04-21 22:11:238651 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108652 request.traffic_annotation =
8653 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298654
8655 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178656 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8657 "Host: www.example.org:443\r\n"
8658 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298659 };
8660
8661 MockRead data_reads[] = {
8662 MockRead("HTTP/1.1 302 Redirect\r\n"),
8663 MockRead("Location: http://login.example.com/\r\n"),
8664 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068665 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298666 };
8667
Ryan Sleevib8d7ea02018-05-07 20:01:018668 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068669 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298670
[email protected]bb88e1d32013-05-03 23:11:078671 session_deps_.socket_factory->AddSocketDataProvider(&data);
8672 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298673
[email protected]49639fa2011-12-20 23:22:418674 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298675
danakj1fd259a02016-04-16 03:17:098676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298678
tfarina42834112016-09-22 13:38:208679 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298681
8682 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018683 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168684 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298685
wezca1070932016-05-26 20:30:528686 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298687
8688 EXPECT_EQ(302, response->headers->response_code());
8689 std::string url;
8690 EXPECT_TRUE(response->headers->IsRedirect(&url));
8691 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208692
8693 // In the case of redirects from proxies, HttpNetworkTransaction returns
8694 // timing for the proxy connection instead of the connection to the host,
8695 // and no send / receive times.
8696 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8697 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168698 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208699
8700 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198701 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208702
8703 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8704 EXPECT_LE(load_timing_info.proxy_resolve_start,
8705 load_timing_info.proxy_resolve_end);
8706 EXPECT_LE(load_timing_info.proxy_resolve_end,
8707 load_timing_info.connect_timing.connect_start);
8708 ExpectConnectTimingHasTimes(
8709 load_timing_info.connect_timing,
8710 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8711
8712 EXPECT_TRUE(load_timing_info.send_start.is_null());
8713 EXPECT_TRUE(load_timing_info.send_end.is_null());
8714 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298715}
8716
8717// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018718TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498719 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8720 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298721
8722 HttpRequestInfo request;
8723 request.method = "GET";
bncce36dca22015-04-21 22:11:238724 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108725 request.traffic_annotation =
8726 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298727
bncdf80d44fd2016-07-15 20:27:418728 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238729 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418730 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088731 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298732 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418733 CreateMockWrite(conn, 0, SYNCHRONOUS),
8734 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298735 };
8736
8737 static const char* const kExtraHeaders[] = {
8738 "location",
8739 "http://login.example.com/",
8740 };
bnc42331402016-07-25 13:36:158741 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238742 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298743 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418744 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298745 };
8746
Ryan Sleevib8d7ea02018-05-07 20:01:018747 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068748 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368749 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298750
[email protected]bb88e1d32013-05-03 23:11:078751 session_deps_.socket_factory->AddSocketDataProvider(&data);
8752 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298753
[email protected]49639fa2011-12-20 23:22:418754 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298755
danakj1fd259a02016-04-16 03:17:098756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298758
tfarina42834112016-09-22 13:38:208759 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298761
8762 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018763 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168764 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298765
wezca1070932016-05-26 20:30:528766 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298767
8768 EXPECT_EQ(302, response->headers->response_code());
8769 std::string url;
8770 EXPECT_TRUE(response->headers->IsRedirect(&url));
8771 EXPECT_EQ("http://login.example.com/", url);
8772}
8773
[email protected]4eddbc732012-08-09 05:40:178774// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018775TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498776 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8777 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298778
8779 HttpRequestInfo request;
8780 request.method = "GET";
bncce36dca22015-04-21 22:11:238781 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108782 request.traffic_annotation =
8783 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298784
8785 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178786 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8787 "Host: www.example.org:443\r\n"
8788 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298789 };
8790
8791 MockRead data_reads[] = {
8792 MockRead("HTTP/1.1 404 Not Found\r\n"),
8793 MockRead("Content-Length: 23\r\n\r\n"),
8794 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068795 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298796 };
8797
Ryan Sleevib8d7ea02018-05-07 20:01:018798 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068799 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298800
[email protected]bb88e1d32013-05-03 23:11:078801 session_deps_.socket_factory->AddSocketDataProvider(&data);
8802 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298803
[email protected]49639fa2011-12-20 23:22:418804 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298805
danakj1fd259a02016-04-16 03:17:098806 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298808
tfarina42834112016-09-22 13:38:208809 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298811
8812 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018813 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298814
ttuttle960fcbf2016-04-19 13:26:328815 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298816}
8817
[email protected]4eddbc732012-08-09 05:40:178818// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018819TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498820 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8821 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298822
8823 HttpRequestInfo request;
8824 request.method = "GET";
bncce36dca22015-04-21 22:11:238825 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108826 request.traffic_annotation =
8827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298828
bncdf80d44fd2016-07-15 20:27:418829 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238830 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418831 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088832 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298833 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418834 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298835 };
8836
8837 static const char* const kExtraHeaders[] = {
8838 "location",
8839 "http://login.example.com/",
8840 };
bnc42331402016-07-25 13:36:158841 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238842 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Bence Békyd74f4382018-02-20 18:26:198843 SpdySerializedFrame body(
8844 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298845 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418846 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138847 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298848 };
8849
Ryan Sleevib8d7ea02018-05-07 20:01:018850 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068851 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368852 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298853
[email protected]bb88e1d32013-05-03 23:11:078854 session_deps_.socket_factory->AddSocketDataProvider(&data);
8855 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298856
[email protected]49639fa2011-12-20 23:22:418857 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298858
danakj1fd259a02016-04-16 03:17:098859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168860 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298861
tfarina42834112016-09-22 13:38:208862 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298864
8865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018866 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298867
ttuttle960fcbf2016-04-19 13:26:328868 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298869}
8870
[email protected]0c5fb722012-02-28 11:50:358871// Test the request-challenge-retry sequence for basic auth, through
8872// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018873TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358874 HttpRequestInfo request;
8875 request.method = "GET";
bncce36dca22015-04-21 22:11:238876 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358877 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298878 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:108879 request.traffic_annotation =
8880 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358881
8882 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598883 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498884 ProxyResolutionService::CreateFixedFromPacResult(
8885 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518886 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078887 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358889
8890 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418891 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238892 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418893 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088894 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388895 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358896
bnc691fda62016-08-12 00:43:168897 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358898 // be issuing -- the final header line contains the credentials.
8899 const char* const kAuthCredentials[] = {
8900 "proxy-authorization", "Basic Zm9vOmJhcg==",
8901 };
bncdf80d44fd2016-07-15 20:27:418902 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348903 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238904 HostPortPair("www.example.org", 443)));
8905 // fetch https://www.example.org/ via HTTP
8906 const char get[] =
8907 "GET / HTTP/1.1\r\n"
8908 "Host: www.example.org\r\n"
8909 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418910 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198911 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358912
8913 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418914 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8915 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358916 };
8917
8918 // The proxy responds to the connect with a 407, using a persistent
8919 // connection.
thestig9d3bb0c2015-01-24 00:49:518920 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358921 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358922 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8923 };
bnc42331402016-07-25 13:36:158924 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418925 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358926
bnc42331402016-07-25 13:36:158927 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358928 const char resp[] = "HTTP/1.1 200 OK\r\n"
8929 "Content-Length: 5\r\n\r\n";
8930
bncdf80d44fd2016-07-15 20:27:418931 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198932 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
bncdf80d44fd2016-07-15 20:27:418933 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198934 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358935 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418936 CreateMockRead(conn_auth_resp, 1, ASYNC),
8937 CreateMockRead(conn_resp, 4, ASYNC),
8938 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8939 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138940 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358941 };
8942
Ryan Sleevib8d7ea02018-05-07 20:01:018943 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:078944 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358945 // Negotiate SPDY to the proxy
8946 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368947 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078948 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358949 // Vanilla SSL to the server
8950 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078951 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358952
8953 TestCompletionCallback callback1;
8954
bnc87dcefc2017-05-25 12:47:588955 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198956 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358957
8958 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358960
8961 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018962 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468963 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358964 log.GetEntries(&entries);
8965 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008966 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8967 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358968 ExpectLogContainsSomewhere(
8969 entries, pos,
mikecirone8b85c432016-09-08 19:11:008970 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8971 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358972
8973 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528974 ASSERT_TRUE(response);
8975 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358976 EXPECT_EQ(407, response->headers->response_code());
8977 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528978 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438979 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358980
8981 TestCompletionCallback callback2;
8982
8983 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8984 callback2.callback());
robpercival214763f2016-07-01 23:27:018985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358986
8987 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018988 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358989
8990 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528991 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358992
8993 EXPECT_TRUE(response->headers->IsKeepAlive());
8994 EXPECT_EQ(200, response->headers->response_code());
8995 EXPECT_EQ(5, response->headers->GetContentLength());
8996 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8997
8998 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528999 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359000
[email protected]029c83b62013-01-24 05:28:209001 LoadTimingInfo load_timing_info;
9002 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9003 TestLoadTimingNotReusedWithPac(load_timing_info,
9004 CONNECT_TIMING_HAS_SSL_TIMES);
9005
[email protected]0c5fb722012-02-28 11:50:359006 trans.reset();
9007 session->CloseAllConnections();
9008}
9009
[email protected]7c6f7ba2012-04-03 04:09:299010// Test that an explicitly trusted SPDY proxy can push a resource from an
9011// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019012TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159013 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199014 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159015 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9016 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299017 HttpRequestInfo request;
9018 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109019 request.traffic_annotation =
9020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299021
[email protected]7c6f7ba2012-04-03 04:09:299022 request.method = "GET";
bncce36dca22015-04-21 22:11:239023 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299024 push_request.method = "GET";
9025 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109026 push_request.traffic_annotation =
9027 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299028
tbansal28e68f82016-02-04 02:56:159029 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599030 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499031 ProxyResolutionService::CreateFixedFromPacResult(
9032 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519033 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079034 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509035
inlinechan894515af2016-12-09 02:40:109036 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509037
danakj1fd259a02016-04-16 03:17:099038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299039
bncdf80d44fd2016-07-15 20:27:419040 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459041 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359042 SpdySerializedFrame stream2_priority(
9043 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299044
9045 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419046 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359047 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299048 };
9049
Bence Béky7bf94362018-01-10 13:19:369050 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9051 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9052
bncdf80d44fd2016-07-15 20:27:419053 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159054 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299055
bncdf80d44fd2016-07-15 20:27:419056 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299057
Bence Békyd74f4382018-02-20 18:26:199058 SpdySerializedFrame stream2_body(
9059 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299060
9061 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369062 CreateMockRead(stream2_syn, 1, ASYNC),
9063 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359064 CreateMockRead(stream1_body, 4, ASYNC),
9065 CreateMockRead(stream2_body, 5, ASYNC),
9066 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299067 };
9068
Ryan Sleevib8d7ea02018-05-07 20:01:019069 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079070 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299071 // Negotiate SPDY to the proxy
9072 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369073 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079074 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299075
bnc87dcefc2017-05-25 12:47:589076 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199077 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299078 TestCompletionCallback callback;
9079 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299081
9082 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019083 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299084 const HttpResponseInfo* response = trans->GetResponseInfo();
9085
bnc87dcefc2017-05-25 12:47:589086 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199087 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509088 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299090
9091 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019092 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299093 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9094
wezca1070932016-05-26 20:30:529095 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299096 EXPECT_TRUE(response->headers->IsKeepAlive());
9097
9098 EXPECT_EQ(200, response->headers->response_code());
9099 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9100
9101 std::string response_data;
9102 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019103 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299104 EXPECT_EQ("hello!", response_data);
9105
[email protected]029c83b62013-01-24 05:28:209106 LoadTimingInfo load_timing_info;
9107 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9108 TestLoadTimingNotReusedWithPac(load_timing_info,
9109 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9110
[email protected]7c6f7ba2012-04-03 04:09:299111 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529112 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299113 EXPECT_EQ(200, push_response->headers->response_code());
9114
9115 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019116 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299117 EXPECT_EQ("pushed", response_data);
9118
[email protected]029c83b62013-01-24 05:28:209119 LoadTimingInfo push_load_timing_info;
9120 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9121 TestLoadTimingReusedWithPac(push_load_timing_info);
9122 // The transactions should share a socket ID, despite being for different
9123 // origins.
9124 EXPECT_EQ(load_timing_info.socket_log_id,
9125 push_load_timing_info.socket_log_id);
9126
[email protected]7c6f7ba2012-04-03 04:09:299127 trans.reset();
9128 push_trans.reset();
9129 session->CloseAllConnections();
9130}
9131
[email protected]8c843192012-04-05 07:15:009132// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019133TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159134 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199135 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159136 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9137 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009138 HttpRequestInfo request;
9139
9140 request.method = "GET";
bncce36dca22015-04-21 22:11:239141 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109142 request.traffic_annotation =
9143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009144
Ramin Halavatica8d5252018-03-12 05:33:499145 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9146 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519147 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079148 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509149
9150 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109151 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509152
danakj1fd259a02016-04-16 03:17:099153 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009154
bncdf80d44fd2016-07-15 20:27:419155 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459156 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009157
bncdf80d44fd2016-07-15 20:27:419158 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089159 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009160
9161 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419162 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009163 };
9164
bncdf80d44fd2016-07-15 20:27:419165 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159166 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009167
bncdf80d44fd2016-07-15 20:27:419168 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009169
bncdf80d44fd2016-07-15 20:27:419170 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559171 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009172
9173 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419174 CreateMockRead(stream1_reply, 1, ASYNC),
9175 CreateMockRead(stream2_syn, 2, ASYNC),
9176 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599177 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009178 };
9179
Ryan Sleevib8d7ea02018-05-07 20:01:019180 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079181 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009182 // Negotiate SPDY to the proxy
9183 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369184 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079185 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009186
bnc87dcefc2017-05-25 12:47:589187 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199188 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009189 TestCompletionCallback callback;
9190 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019191 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009192
9193 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019194 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009195 const HttpResponseInfo* response = trans->GetResponseInfo();
9196
wezca1070932016-05-26 20:30:529197 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009198 EXPECT_TRUE(response->headers->IsKeepAlive());
9199
9200 EXPECT_EQ(200, response->headers->response_code());
9201 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9202
9203 std::string response_data;
9204 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019205 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009206 EXPECT_EQ("hello!", response_data);
9207
9208 trans.reset();
9209 session->CloseAllConnections();
9210}
9211
tbansal8ef1d3e2016-02-03 04:05:429212// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9213// resources.
bncd16676a2016-07-20 16:23:019214TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159215 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199216 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159217 proxy_delegate->set_trusted_spdy_proxy(
9218 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9219
tbansal8ef1d3e2016-02-03 04:05:429220 HttpRequestInfo request;
9221
9222 request.method = "GET";
9223 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109224 request.traffic_annotation =
9225 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429226
9227 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499228 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9229 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429230 BoundTestNetLog log;
9231 session_deps_.net_log = log.bound().net_log();
9232
9233 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109234 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429235
danakj1fd259a02016-04-16 03:17:099236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429237
bncdf80d44fd2016-07-15 20:27:419238 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459239 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359240 SpdySerializedFrame stream2_priority(
9241 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429242
9243 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419244 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359245 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429246 };
9247
bncdf80d44fd2016-07-15 20:27:419248 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159249 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429250
bncdf80d44fd2016-07-15 20:27:419251 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339252 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499253
bncdf80d44fd2016-07-15 20:27:419254 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429255
bncdf80d44fd2016-07-15 20:27:419256 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159257 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429258
bncdf80d44fd2016-07-15 20:27:419259 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429260
9261 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419262 CreateMockRead(stream1_reply, 1, ASYNC),
9263 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359264 CreateMockRead(stream1_body, 4, ASYNC),
9265 CreateMockRead(stream2_body, 5, ASYNC),
9266 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429267 };
9268
Ryan Sleevib8d7ea02018-05-07 20:01:019269 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:429270 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9271 // Negotiate SPDY to the proxy
9272 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369273 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429274 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9275
bnc87dcefc2017-05-25 12:47:589276 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199277 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429278 TestCompletionCallback callback;
9279 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429281
9282 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019283 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429284 const HttpResponseInfo* response = trans->GetResponseInfo();
9285
wezca1070932016-05-26 20:30:529286 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429287 EXPECT_TRUE(response->headers->IsKeepAlive());
9288
9289 EXPECT_EQ(200, response->headers->response_code());
9290 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9291
9292 std::string response_data;
9293 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019294 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429295 EXPECT_EQ("hello!", response_data);
9296
9297 trans.reset();
9298 session->CloseAllConnections();
9299}
9300
[email protected]2df19bb2010-08-25 20:13:469301// Test HTTPS connections to a site with a bad certificate, going through an
9302// HTTPS proxy
bncd16676a2016-07-20 16:23:019303TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499304 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9305 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469306
9307 HttpRequestInfo request;
9308 request.method = "GET";
bncce36dca22015-04-21 22:11:239309 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109310 request.traffic_annotation =
9311 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469312
9313 // Attempt to fetch the URL from a server with a bad cert
9314 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179315 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9316 "Host: www.example.org:443\r\n"
9317 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469318 };
9319
9320 MockRead bad_cert_reads[] = {
9321 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069322 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469323 };
9324
9325 // Attempt to fetch the URL with a good cert
9326 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179327 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9328 "Host: www.example.org:443\r\n"
9329 "Proxy-Connection: keep-alive\r\n\r\n"),
9330 MockWrite("GET / HTTP/1.1\r\n"
9331 "Host: www.example.org\r\n"
9332 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469333 };
9334
9335 MockRead good_cert_reads[] = {
9336 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9337 MockRead("HTTP/1.0 200 OK\r\n"),
9338 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9339 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069340 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469341 };
9342
Ryan Sleevib8d7ea02018-05-07 20:01:019343 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
9344 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:069345 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9346 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469347
9348 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079349 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9350 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469352
9353 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9355 session_deps_.socket_factory->AddSocketDataProvider(&data);
9356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469357
[email protected]49639fa2011-12-20 23:22:419358 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469359
danakj1fd259a02016-04-16 03:17:099360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469362
tfarina42834112016-09-22 13:38:209363 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469365
9366 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019367 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469368
bnc691fda62016-08-12 00:43:169369 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469371
9372 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019373 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469374
bnc691fda62016-08-12 00:43:169375 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469376
wezca1070932016-05-26 20:30:529377 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469378 EXPECT_EQ(100, response->headers->GetContentLength());
9379}
9380
bncd16676a2016-07-20 16:23:019381TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429382 HttpRequestInfo request;
9383 request.method = "GET";
bncce36dca22015-04-21 22:11:239384 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439385 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9386 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109387 request.traffic_annotation =
9388 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429389
danakj1fd259a02016-04-16 03:17:099390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169391 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279392
[email protected]1c773ea12009-04-28 19:58:429393 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239394 MockWrite(
9395 "GET / HTTP/1.1\r\n"
9396 "Host: www.example.org\r\n"
9397 "Connection: keep-alive\r\n"
9398 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429399 };
9400
9401 // Lastly, the server responds with the actual content.
9402 MockRead data_reads[] = {
9403 MockRead("HTTP/1.0 200 OK\r\n"),
9404 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9405 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069406 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429407 };
9408
Ryan Sleevib8d7ea02018-05-07 20:01:019409 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079410 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429411
[email protected]49639fa2011-12-20 23:22:419412 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429413
tfarina42834112016-09-22 13:38:209414 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429416
9417 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019418 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429419}
9420
bncd16676a2016-07-20 16:23:019421TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299422 HttpRequestInfo request;
9423 request.method = "GET";
bncce36dca22015-04-21 22:11:239424 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299425 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9426 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109427 request.traffic_annotation =
9428 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299429
Ramin Halavatica8d5252018-03-12 05:33:499430 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9431 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099432 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279434
[email protected]da81f132010-08-18 23:39:299435 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179436 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9437 "Host: www.example.org:443\r\n"
9438 "Proxy-Connection: keep-alive\r\n"
9439 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299440 };
9441 MockRead data_reads[] = {
9442 // Return an error, so the transaction stops here (this test isn't
9443 // interested in the rest).
9444 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9445 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9446 MockRead("Proxy-Connection: close\r\n\r\n"),
9447 };
9448
Ryan Sleevib8d7ea02018-05-07 20:01:019449 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079450 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299451
[email protected]49639fa2011-12-20 23:22:419452 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299453
tfarina42834112016-09-22 13:38:209454 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299456
9457 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019458 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299459}
9460
bncd16676a2016-07-20 16:23:019461TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429462 HttpRequestInfo request;
9463 request.method = "GET";
bncce36dca22015-04-21 22:11:239464 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169465 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9466 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:109467 request.traffic_annotation =
9468 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429469
danakj1fd259a02016-04-16 03:17:099470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279472
[email protected]1c773ea12009-04-28 19:58:429473 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239474 MockWrite(
9475 "GET / HTTP/1.1\r\n"
9476 "Host: www.example.org\r\n"
9477 "Connection: keep-alive\r\n"
9478 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429479 };
9480
9481 // Lastly, the server responds with the actual content.
9482 MockRead data_reads[] = {
9483 MockRead("HTTP/1.0 200 OK\r\n"),
9484 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9485 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069486 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429487 };
9488
Ryan Sleevib8d7ea02018-05-07 20:01:019489 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079490 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429491
[email protected]49639fa2011-12-20 23:22:419492 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429493
tfarina42834112016-09-22 13:38:209494 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019495 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429496
9497 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019498 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429499}
9500
bncd16676a2016-07-20 16:23:019501TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429502 HttpRequestInfo request;
9503 request.method = "POST";
bncce36dca22015-04-21 22:11:239504 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109505 request.traffic_annotation =
9506 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429507
danakj1fd259a02016-04-16 03:17:099508 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279510
[email protected]1c773ea12009-04-28 19:58:429511 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239512 MockWrite(
9513 "POST / HTTP/1.1\r\n"
9514 "Host: www.example.org\r\n"
9515 "Connection: keep-alive\r\n"
9516 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429517 };
9518
9519 // Lastly, the server responds with the actual content.
9520 MockRead data_reads[] = {
9521 MockRead("HTTP/1.0 200 OK\r\n"),
9522 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9523 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069524 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429525 };
9526
Ryan Sleevib8d7ea02018-05-07 20:01:019527 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079528 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429529
[email protected]49639fa2011-12-20 23:22:419530 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429531
tfarina42834112016-09-22 13:38:209532 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429534
9535 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019536 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429537}
9538
bncd16676a2016-07-20 16:23:019539TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429540 HttpRequestInfo request;
9541 request.method = "PUT";
bncce36dca22015-04-21 22:11:239542 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109543 request.traffic_annotation =
9544 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429545
danakj1fd259a02016-04-16 03:17:099546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279548
[email protected]1c773ea12009-04-28 19:58:429549 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239550 MockWrite(
9551 "PUT / HTTP/1.1\r\n"
9552 "Host: www.example.org\r\n"
9553 "Connection: keep-alive\r\n"
9554 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429555 };
9556
9557 // Lastly, the server responds with the actual content.
9558 MockRead data_reads[] = {
9559 MockRead("HTTP/1.0 200 OK\r\n"),
9560 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9561 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069562 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429563 };
9564
Ryan Sleevib8d7ea02018-05-07 20:01:019565 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079566 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429567
[email protected]49639fa2011-12-20 23:22:419568 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429569
tfarina42834112016-09-22 13:38:209570 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429572
9573 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019574 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429575}
9576
bncd16676a2016-07-20 16:23:019577TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429578 HttpRequestInfo request;
9579 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239580 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109581 request.traffic_annotation =
9582 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429583
danakj1fd259a02016-04-16 03:17:099584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279586
[email protected]1c773ea12009-04-28 19:58:429587 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139588 MockWrite("HEAD / HTTP/1.1\r\n"
9589 "Host: www.example.org\r\n"
9590 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429591 };
9592
9593 // Lastly, the server responds with the actual content.
9594 MockRead data_reads[] = {
9595 MockRead("HTTP/1.0 200 OK\r\n"),
9596 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9597 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069598 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429599 };
9600
Ryan Sleevib8d7ea02018-05-07 20:01:019601 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079602 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429603
[email protected]49639fa2011-12-20 23:22:419604 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429605
tfarina42834112016-09-22 13:38:209606 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429608
9609 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019610 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429611}
9612
bncd16676a2016-07-20 16:23:019613TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429614 HttpRequestInfo request;
9615 request.method = "GET";
bncce36dca22015-04-21 22:11:239616 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429617 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109618 request.traffic_annotation =
9619 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429620
danakj1fd259a02016-04-16 03:17:099621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169622 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279623
[email protected]1c773ea12009-04-28 19:58:429624 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239625 MockWrite(
9626 "GET / HTTP/1.1\r\n"
9627 "Host: www.example.org\r\n"
9628 "Connection: keep-alive\r\n"
9629 "Pragma: no-cache\r\n"
9630 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429631 };
9632
9633 // Lastly, the server responds with the actual content.
9634 MockRead data_reads[] = {
9635 MockRead("HTTP/1.0 200 OK\r\n"),
9636 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9637 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069638 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429639 };
9640
Ryan Sleevib8d7ea02018-05-07 20:01:019641 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079642 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429643
[email protected]49639fa2011-12-20 23:22:419644 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429645
tfarina42834112016-09-22 13:38:209646 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429648
9649 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019650 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429651}
9652
bncd16676a2016-07-20 16:23:019653TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429654 HttpRequestInfo request;
9655 request.method = "GET";
bncce36dca22015-04-21 22:11:239656 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429657 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109658 request.traffic_annotation =
9659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429660
danakj1fd259a02016-04-16 03:17:099661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279663
[email protected]1c773ea12009-04-28 19:58:429664 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239665 MockWrite(
9666 "GET / HTTP/1.1\r\n"
9667 "Host: www.example.org\r\n"
9668 "Connection: keep-alive\r\n"
9669 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429670 };
9671
9672 // Lastly, the server responds with the actual content.
9673 MockRead data_reads[] = {
9674 MockRead("HTTP/1.0 200 OK\r\n"),
9675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9676 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069677 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429678 };
9679
Ryan Sleevib8d7ea02018-05-07 20:01:019680 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079681 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429682
[email protected]49639fa2011-12-20 23:22:419683 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429684
tfarina42834112016-09-22 13:38:209685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429687
9688 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019689 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429690}
9691
bncd16676a2016-07-20 16:23:019692TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429693 HttpRequestInfo request;
9694 request.method = "GET";
bncce36dca22015-04-21 22:11:239695 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439696 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:109697 request.traffic_annotation =
9698 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429699
danakj1fd259a02016-04-16 03:17:099700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279702
[email protected]1c773ea12009-04-28 19:58:429703 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239704 MockWrite(
9705 "GET / HTTP/1.1\r\n"
9706 "Host: www.example.org\r\n"
9707 "Connection: keep-alive\r\n"
9708 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429709 };
9710
9711 // Lastly, the server responds with the actual content.
9712 MockRead data_reads[] = {
9713 MockRead("HTTP/1.0 200 OK\r\n"),
9714 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9715 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069716 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429717 };
9718
Ryan Sleevib8d7ea02018-05-07 20:01:019719 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079720 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429721
[email protected]49639fa2011-12-20 23:22:419722 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429723
tfarina42834112016-09-22 13:38:209724 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429726
9727 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019728 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429729}
9730
bncd16676a2016-07-20 16:23:019731TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479732 HttpRequestInfo request;
9733 request.method = "GET";
bncce36dca22015-04-21 22:11:239734 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439735 request.extra_headers.SetHeader("referer", "www.foo.com");
9736 request.extra_headers.SetHeader("hEllo", "Kitty");
9737 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:109738 request.traffic_annotation =
9739 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479740
danakj1fd259a02016-04-16 03:17:099741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279743
[email protected]270c6412010-03-29 22:02:479744 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239745 MockWrite(
9746 "GET / HTTP/1.1\r\n"
9747 "Host: www.example.org\r\n"
9748 "Connection: keep-alive\r\n"
9749 "referer: www.foo.com\r\n"
9750 "hEllo: Kitty\r\n"
9751 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479752 };
9753
9754 // Lastly, the server responds with the actual content.
9755 MockRead data_reads[] = {
9756 MockRead("HTTP/1.0 200 OK\r\n"),
9757 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9758 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069759 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479760 };
9761
Ryan Sleevib8d7ea02018-05-07 20:01:019762 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079763 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479764
[email protected]49639fa2011-12-20 23:22:419765 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479766
tfarina42834112016-09-22 13:38:209767 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479769
9770 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019771 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479772}
9773
bncd16676a2016-07-20 16:23:019774TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279775 HttpRequestInfo request;
9776 request.method = "GET";
bncce36dca22015-04-21 22:11:239777 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109778 request.traffic_annotation =
9779 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279780
Lily Houghton8c2f97d2018-01-22 05:06:599781 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499782 ProxyResolutionService::CreateFixedFromPacResult(
9783 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519784 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079785 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029786
danakj1fd259a02016-04-16 03:17:099787 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169788 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029789
[email protected]3cd17242009-06-23 02:59:029790 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9791 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9792
9793 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239794 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9795 MockWrite(
9796 "GET / HTTP/1.1\r\n"
9797 "Host: www.example.org\r\n"
9798 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029799
9800 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069801 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029802 MockRead("HTTP/1.0 200 OK\r\n"),
9803 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9804 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069805 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029806 };
9807
Ryan Sleevib8d7ea02018-05-07 20:01:019808 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079809 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029810
[email protected]49639fa2011-12-20 23:22:419811 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029812
tfarina42834112016-09-22 13:38:209813 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029815
9816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019817 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029818
bnc691fda62016-08-12 00:43:169819 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529820 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029821
tbansal2ecbbc72016-10-06 17:15:479822 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209823 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169824 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209825 TestLoadTimingNotReusedWithPac(load_timing_info,
9826 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9827
[email protected]3cd17242009-06-23 02:59:029828 std::string response_text;
bnc691fda62016-08-12 00:43:169829 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019830 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029831 EXPECT_EQ("Payload", response_text);
9832}
9833
bncd16676a2016-07-20 16:23:019834TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279835 HttpRequestInfo request;
9836 request.method = "GET";
bncce36dca22015-04-21 22:11:239837 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109838 request.traffic_annotation =
9839 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279840
Lily Houghton8c2f97d2018-01-22 05:06:599841 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499842 ProxyResolutionService::CreateFixedFromPacResult(
9843 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519844 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079845 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029846
danakj1fd259a02016-04-16 03:17:099847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029849
[email protected]3cd17242009-06-23 02:59:029850 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9851 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9852
9853 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239854 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9855 arraysize(write_buffer)),
9856 MockWrite(
9857 "GET / HTTP/1.1\r\n"
9858 "Host: www.example.org\r\n"
9859 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029860
9861 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019862 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9863 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359864 MockRead("HTTP/1.0 200 OK\r\n"),
9865 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9866 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069867 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359868 };
9869
Ryan Sleevib8d7ea02018-05-07 20:01:019870 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359872
[email protected]8ddf8322012-02-23 18:08:069873 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359875
[email protected]49639fa2011-12-20 23:22:419876 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359877
tfarina42834112016-09-22 13:38:209878 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019879 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359880
9881 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019882 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359883
[email protected]029c83b62013-01-24 05:28:209884 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169885 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209886 TestLoadTimingNotReusedWithPac(load_timing_info,
9887 CONNECT_TIMING_HAS_SSL_TIMES);
9888
bnc691fda62016-08-12 00:43:169889 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529890 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479891 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359892
9893 std::string response_text;
bnc691fda62016-08-12 00:43:169894 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019895 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359896 EXPECT_EQ("Payload", response_text);
9897}
9898
bncd16676a2016-07-20 16:23:019899TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209900 HttpRequestInfo request;
9901 request.method = "GET";
bncce36dca22015-04-21 22:11:239902 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109903 request.traffic_annotation =
9904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209905
Ramin Halavatica8d5252018-03-12 05:33:499906 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9907 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519908 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079909 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209910
danakj1fd259a02016-04-16 03:17:099911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169912 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209913
9914 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9915 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9916
9917 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239918 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9919 MockWrite(
9920 "GET / HTTP/1.1\r\n"
9921 "Host: www.example.org\r\n"
9922 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209923
9924 MockRead data_reads[] = {
9925 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9926 MockRead("HTTP/1.0 200 OK\r\n"),
9927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9928 MockRead("Payload"),
9929 MockRead(SYNCHRONOUS, OK)
9930 };
9931
Ryan Sleevib8d7ea02018-05-07 20:01:019932 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079933 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209934
9935 TestCompletionCallback callback;
9936
tfarina42834112016-09-22 13:38:209937 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209939
9940 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019941 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209942
bnc691fda62016-08-12 00:43:169943 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529944 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209945
9946 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169947 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209948 TestLoadTimingNotReused(load_timing_info,
9949 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9950
9951 std::string response_text;
bnc691fda62016-08-12 00:43:169952 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019953 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209954 EXPECT_EQ("Payload", response_text);
9955}
9956
bncd16676a2016-07-20 16:23:019957TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279958 HttpRequestInfo request;
9959 request.method = "GET";
bncce36dca22015-04-21 22:11:239960 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109961 request.traffic_annotation =
9962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279963
Lily Houghton8c2f97d2018-01-22 05:06:599964 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499965 ProxyResolutionService::CreateFixedFromPacResult(
9966 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519967 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079968 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359969
danakj1fd259a02016-04-16 03:17:099970 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169971 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359972
[email protected]e0c27be2009-07-15 13:09:359973 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9974 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379975 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239976 0x05, // Version
9977 0x01, // Command (CONNECT)
9978 0x00, // Reserved.
9979 0x03, // Address type (DOMAINNAME).
9980 0x0F, // Length of domain (15)
9981 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9982 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379983 };
[email protected]e0c27be2009-07-15 13:09:359984 const char kSOCKS5OkResponse[] =
9985 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9986
9987 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239988 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9989 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9990 MockWrite(
9991 "GET / HTTP/1.1\r\n"
9992 "Host: www.example.org\r\n"
9993 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359994
9995 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019996 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9997 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359998 MockRead("HTTP/1.0 200 OK\r\n"),
9999 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10000 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610001 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510002 };
10003
Ryan Sleevib8d7ea02018-05-07 20:01:0110004 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710005 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510006
[email protected]49639fa2011-12-20 23:22:4110007 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510008
tfarina42834112016-09-22 13:38:2010009 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510011
10012 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110013 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510014
bnc691fda62016-08-12 00:43:1610015 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210016 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710017 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510018
[email protected]029c83b62013-01-24 05:28:2010019 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610020 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010021 TestLoadTimingNotReusedWithPac(load_timing_info,
10022 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10023
[email protected]e0c27be2009-07-15 13:09:3510024 std::string response_text;
bnc691fda62016-08-12 00:43:1610025 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110026 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510027 EXPECT_EQ("Payload", response_text);
10028}
10029
bncd16676a2016-07-20 16:23:0110030TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710031 HttpRequestInfo request;
10032 request.method = "GET";
bncce36dca22015-04-21 22:11:2310033 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010034 request.traffic_annotation =
10035 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710036
Lily Houghton8c2f97d2018-01-22 05:06:5910037 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910038 ProxyResolutionService::CreateFixedFromPacResult(
10039 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110040 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710041 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510042
danakj1fd259a02016-04-16 03:17:0910043 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510045
[email protected]e0c27be2009-07-15 13:09:3510046 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10047 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710048 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310049 0x05, // Version
10050 0x01, // Command (CONNECT)
10051 0x00, // Reserved.
10052 0x03, // Address type (DOMAINNAME).
10053 0x0F, // Length of domain (15)
10054 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10055 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710056 };
10057
[email protected]e0c27be2009-07-15 13:09:3510058 const char kSOCKS5OkResponse[] =
10059 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10060
10061 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310062 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10063 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10064 arraysize(kSOCKS5OkRequest)),
10065 MockWrite(
10066 "GET / HTTP/1.1\r\n"
10067 "Host: www.example.org\r\n"
10068 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510069
10070 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110071 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10072 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210073 MockRead("HTTP/1.0 200 OK\r\n"),
10074 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10075 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610076 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210077 };
10078
Ryan Sleevib8d7ea02018-05-07 20:01:0110079 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710080 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210081
[email protected]8ddf8322012-02-23 18:08:0610082 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710083 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210084
[email protected]49639fa2011-12-20 23:22:4110085 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210086
tfarina42834112016-09-22 13:38:2010087 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210089
10090 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110091 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210092
bnc691fda62016-08-12 00:43:1610093 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210094 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710095 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210096
[email protected]029c83b62013-01-24 05:28:2010097 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610098 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010099 TestLoadTimingNotReusedWithPac(load_timing_info,
10100 CONNECT_TIMING_HAS_SSL_TIMES);
10101
[email protected]3cd17242009-06-23 02:59:0210102 std::string response_text;
bnc691fda62016-08-12 00:43:1610103 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110104 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210105 EXPECT_EQ("Payload", response_text);
10106}
10107
[email protected]448d4ca52012-03-04 04:12:2310108namespace {
10109
[email protected]04e5be32009-06-26 20:00:3110110// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610111
10112struct GroupNameTest {
10113 std::string proxy_server;
10114 std::string url;
10115 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810116 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610117};
10118
danakj1fd259a02016-04-16 03:17:0910119std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710120 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910121 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610122
bnc525e175a2016-06-20 12:36:4010123 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310124 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110125 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210126 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110127 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210128 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610129 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610130
10131 return session;
10132}
10133
mmenkee65e7af2015-10-13 17:16:4210134int GroupNameTransactionHelper(const std::string& url,
10135 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610136 HttpRequestInfo request;
10137 request.method = "GET";
10138 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1010139 request.traffic_annotation =
10140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610141
bnc691fda62016-08-12 00:43:1610142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710143
[email protected]49639fa2011-12-20 23:22:4110144 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610145
10146 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010147 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610148}
10149
[email protected]448d4ca52012-03-04 04:12:2310150} // namespace
10151
bncd16676a2016-07-20 16:23:0110152TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610153 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310154 {
10155 "", // unused
10156 "http://www.example.org/direct",
10157 "www.example.org:80",
10158 false,
10159 },
10160 {
10161 "", // unused
10162 "http://[2001:1418:13:1::25]/direct",
10163 "[2001:1418:13:1::25]:80",
10164 false,
10165 },
[email protected]04e5be32009-06-26 20:00:3110166
bncce36dca22015-04-21 22:11:2310167 // SSL Tests
10168 {
10169 "", // unused
10170 "https://www.example.org/direct_ssl",
10171 "ssl/www.example.org:443",
10172 true,
10173 },
10174 {
10175 "", // unused
10176 "https://[2001:1418:13:1::25]/direct",
10177 "ssl/[2001:1418:13:1::25]:443",
10178 true,
10179 },
10180 {
10181 "", // unused
bncaa60ff402016-06-22 19:12:4210182 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310183 "ssl/host.with.alternate:443",
10184 true,
10185 },
[email protected]2d731a32010-04-29 01:04:0610186 };
[email protected]2ff8b312010-04-26 22:20:5410187
viettrungluue4a8b882014-10-16 06:17:3810188 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910189 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910190 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10191 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910192 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010193 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610194
mmenkee65e7af2015-10-13 17:16:4210195 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810196 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810197 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310198 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810199 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910200 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210201 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10202 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810203 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610204
10205 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210206 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910207 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810208 EXPECT_EQ(tests[i].expected_group_name,
10209 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910210 } else {
[email protected]e60e47a2010-07-14 03:37:1810211 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810212 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910213 }
10214 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10215 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10216 // When SSL proxy is not in use, socket must be requested from
10217 // |transport_conn_pool|.
10218 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610219 }
[email protected]2d731a32010-04-29 01:04:0610220}
10221
bncd16676a2016-07-20 16:23:0110222TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610223 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310224 {
Matt Menked1eb6d42018-01-17 04:54:0610225 "http_proxy", "http://www.example.org/http_proxy_normal",
10226 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310227 },
[email protected]2d731a32010-04-29 01:04:0610228
bncce36dca22015-04-21 22:11:2310229 // SSL Tests
10230 {
Matt Menked1eb6d42018-01-17 04:54:0610231 "http_proxy", "https://www.example.org/http_connect_ssl",
10232 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310233 },
[email protected]af3490e2010-10-16 21:02:2910234
bncce36dca22015-04-21 22:11:2310235 {
Matt Menked1eb6d42018-01-17 04:54:0610236 "http_proxy", "https://host.with.alternate/direct",
10237 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310238 },
[email protected]45499252013-01-23 17:12:5610239
bncce36dca22015-04-21 22:11:2310240 {
Matt Menked1eb6d42018-01-17 04:54:0610241 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10242 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310243 },
[email protected]2d731a32010-04-29 01:04:0610244 };
10245
viettrungluue4a8b882014-10-16 06:17:3810246 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910247 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910248 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10249 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910250 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010251 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610252
mmenkee65e7af2015-10-13 17:16:4210253 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610254
[email protected]e60e47a2010-07-14 03:37:1810255 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310256 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410257 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310258 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410259 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910260 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910261 mock_pool_manager->SetSocketPoolForHTTPProxy(
10262 proxy_host, base::WrapUnique(http_proxy_pool));
10263 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10264 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810265 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610266
10267 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210268 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810269 if (tests[i].ssl)
10270 EXPECT_EQ(tests[i].expected_group_name,
10271 ssl_conn_pool->last_group_name_received());
10272 else
10273 EXPECT_EQ(tests[i].expected_group_name,
10274 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610275 }
[email protected]2d731a32010-04-29 01:04:0610276}
10277
bncd16676a2016-07-20 16:23:0110278TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610279 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310280 {
10281 "socks4://socks_proxy:1080",
10282 "http://www.example.org/socks4_direct",
10283 "socks4/www.example.org:80",
10284 false,
10285 },
10286 {
10287 "socks5://socks_proxy:1080",
10288 "http://www.example.org/socks5_direct",
10289 "socks5/www.example.org:80",
10290 false,
10291 },
[email protected]2d731a32010-04-29 01:04:0610292
bncce36dca22015-04-21 22:11:2310293 // SSL Tests
10294 {
10295 "socks4://socks_proxy:1080",
10296 "https://www.example.org/socks4_ssl",
10297 "socks4/ssl/www.example.org:443",
10298 true,
10299 },
10300 {
10301 "socks5://socks_proxy:1080",
10302 "https://www.example.org/socks5_ssl",
10303 "socks5/ssl/www.example.org:443",
10304 true,
10305 },
[email protected]af3490e2010-10-16 21:02:2910306
bncce36dca22015-04-21 22:11:2310307 {
10308 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210309 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310310 "socks4/ssl/host.with.alternate:443",
10311 true,
10312 },
[email protected]04e5be32009-06-26 20:00:3110313 };
10314
viettrungluue4a8b882014-10-16 06:17:3810315 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910316 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910317 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10318 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910319 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010320 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210321
mmenkee65e7af2015-10-13 17:16:4210322 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110323
[email protected]e60e47a2010-07-14 03:37:1810324 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310325 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410326 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310327 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410328 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910329 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910330 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10331 proxy_host, base::WrapUnique(socks_conn_pool));
10332 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10333 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810334 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110335
bnc691fda62016-08-12 00:43:1610336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110337
[email protected]2d731a32010-04-29 01:04:0610338 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210339 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810340 if (tests[i].ssl)
10341 EXPECT_EQ(tests[i].expected_group_name,
10342 ssl_conn_pool->last_group_name_received());
10343 else
10344 EXPECT_EQ(tests[i].expected_group_name,
10345 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110346 }
10347}
10348
bncd16676a2016-07-20 16:23:0110349TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710350 HttpRequestInfo request;
10351 request.method = "GET";
bncce36dca22015-04-21 22:11:2310352 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010353 request.traffic_annotation =
10354 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710355
Ramin Halavatica8d5252018-03-12 05:33:4910356 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10357 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210358
[email protected]69719062010-01-05 20:09:2110359 // This simulates failure resolving all hostnames; that means we will fail
10360 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710361 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210362
danakj1fd259a02016-04-16 03:17:0910363 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510365
[email protected]49639fa2011-12-20 23:22:4110366 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510367
tfarina42834112016-09-22 13:38:2010368 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510370
[email protected]9172a982009-06-06 00:30:2510371 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110372 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510373}
10374
Miriam Gershenson2a01b162018-03-22 22:54:4710375// LOAD_BYPASS_CACHE should trigger the host cache bypass.
10376TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2710377 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010378 HttpRequestInfo request_info;
10379 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4710380 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1010381 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010382 request_info.traffic_annotation =
10383 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710384
[email protected]a2c2fb92009-07-18 07:31:0410385 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910386 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210387
danakj1fd259a02016-04-16 03:17:0910388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810390
bncce36dca22015-04-21 22:11:2310391 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810392 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910393 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010394 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710395 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310396 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010397 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010398 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710400 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110401 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810402
10403 // Verify that it was added to host cache, by doing a subsequent async lookup
10404 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010405 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710406 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310407 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010408 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010409 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110410 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810411
bncce36dca22015-04-21 22:11:2310412 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810413 // we can tell if the next lookup hit the cache, or the "network".
10414 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310415 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810416
10417 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10418 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610419 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0110420 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710421 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810422
[email protected]3b9cca42009-06-16 01:08:2810423 // Run the request.
tfarina42834112016-09-22 13:38:2010424 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110425 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110426 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810427
10428 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310429 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110430 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810431}
10432
[email protected]0877e3d2009-10-17 22:29:5710433// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110434TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710435 HttpRequestInfo request;
10436 request.method = "GET";
10437 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010438 request.traffic_annotation =
10439 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710440
10441 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610442 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710443 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110444 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0710445 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910446 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710447
[email protected]49639fa2011-12-20 23:22:4110448 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710449
bnc691fda62016-08-12 00:43:1610450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710451
tfarina42834112016-09-22 13:38:2010452 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710454
10455 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110456 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910457
10458 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610459 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910460 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710461}
10462
zmo9528c9f42015-08-04 22:12:0810463// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110464TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710465 HttpRequestInfo request;
10466 request.method = "GET";
10467 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010468 request.traffic_annotation =
10469 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710470
10471 MockRead data_reads[] = {
10472 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610473 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710474 };
10475
Ryan Sleevib8d7ea02018-05-07 20:01:0110476 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710477 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910478 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710479
[email protected]49639fa2011-12-20 23:22:4110480 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710481
bnc691fda62016-08-12 00:43:1610482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710483
tfarina42834112016-09-22 13:38:2010484 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710486
10487 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110488 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810489
bnc691fda62016-08-12 00:43:1610490 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210491 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810492
wezca1070932016-05-26 20:30:5210493 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810494 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10495
10496 std::string response_data;
bnc691fda62016-08-12 00:43:1610497 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110498 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810499 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910500
10501 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610502 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910503 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710504}
10505
10506// Make sure that a dropped connection while draining the body for auth
10507// restart does the right thing.
bncd16676a2016-07-20 16:23:0110508TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710509 HttpRequestInfo request;
10510 request.method = "GET";
bncce36dca22015-04-21 22:11:2310511 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010512 request.traffic_annotation =
10513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710514
10515 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310516 MockWrite(
10517 "GET / HTTP/1.1\r\n"
10518 "Host: www.example.org\r\n"
10519 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710520 };
10521
10522 MockRead data_reads1[] = {
10523 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10524 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10525 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10526 MockRead("Content-Length: 14\r\n\r\n"),
10527 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610528 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710529 };
10530
Ryan Sleevib8d7ea02018-05-07 20:01:0110531 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0710532 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710533
bnc691fda62016-08-12 00:43:1610534 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710535 // be issuing -- the final header line contains the credentials.
10536 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310537 MockWrite(
10538 "GET / HTTP/1.1\r\n"
10539 "Host: www.example.org\r\n"
10540 "Connection: keep-alive\r\n"
10541 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710542 };
10543
10544 // Lastly, the server responds with the actual content.
10545 MockRead data_reads2[] = {
10546 MockRead("HTTP/1.1 200 OK\r\n"),
10547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10548 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610549 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710550 };
10551
Ryan Sleevib8d7ea02018-05-07 20:01:0110552 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0710553 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710555
[email protected]49639fa2011-12-20 23:22:4110556 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710557
bnc691fda62016-08-12 00:43:1610558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010559
tfarina42834112016-09-22 13:38:2010560 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710562
10563 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110564 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710565
bnc691fda62016-08-12 00:43:1610566 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210567 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410568 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710569
[email protected]49639fa2011-12-20 23:22:4110570 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710571
bnc691fda62016-08-12 00:43:1610572 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710574
10575 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110576 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710577
bnc691fda62016-08-12 00:43:1610578 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210579 ASSERT_TRUE(response);
10580 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710581 EXPECT_EQ(100, response->headers->GetContentLength());
10582}
10583
10584// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110585TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910586 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10587 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710588
10589 HttpRequestInfo request;
10590 request.method = "GET";
bncce36dca22015-04-21 22:11:2310591 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010592 request.traffic_annotation =
10593 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710594
10595 MockRead proxy_reads[] = {
10596 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610597 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710598 };
10599
Ryan Sleevib8d7ea02018-05-07 20:01:0110600 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0610601 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710602
[email protected]bb88e1d32013-05-03 23:11:0710603 session_deps_.socket_factory->AddSocketDataProvider(&data);
10604 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710605
[email protected]49639fa2011-12-20 23:22:4110606 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710607
[email protected]bb88e1d32013-05-03 23:11:0710608 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710609
danakj1fd259a02016-04-16 03:17:0910610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710612
tfarina42834112016-09-22 13:38:2010613 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110614 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710615
10616 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110617 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710618}
10619
bncd16676a2016-07-20 16:23:0110620TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610621 HttpRequestInfo request;
10622 request.method = "GET";
bncce36dca22015-04-21 22:11:2310623 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010624 request.traffic_annotation =
10625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610626
danakj1fd259a02016-04-16 03:17:0910627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710629
[email protected]e22e1362009-11-23 21:31:1210630 MockRead data_reads[] = {
10631 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610632 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210633 };
[email protected]9492e4a2010-02-24 00:58:4610634
Ryan Sleevib8d7ea02018-05-07 20:01:0110635 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610637
[email protected]49639fa2011-12-20 23:22:4110638 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610639
tfarina42834112016-09-22 13:38:2010640 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610642
robpercival214763f2016-07-01 23:27:0110643 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610644
bnc691fda62016-08-12 00:43:1610645 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210646 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610647
wezca1070932016-05-26 20:30:5210648 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610649 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10650
10651 std::string response_data;
bnc691fda62016-08-12 00:43:1610652 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110653 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210654}
10655
bncd16676a2016-07-20 16:23:0110656TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510657 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210658 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410659 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110660 UploadFileElementReader::ScopedOverridingContentLengthForTests
10661 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310662
danakj1fd259a02016-04-16 03:17:0910663 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910664 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410665 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710666 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210667 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710668
10669 HttpRequestInfo request;
10670 request.method = "POST";
bncce36dca22015-04-21 22:11:2310671 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710672 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010673 request.traffic_annotation =
10674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710675
danakj1fd259a02016-04-16 03:17:0910676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310678
10679 MockRead data_reads[] = {
10680 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10681 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610682 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310683 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110684 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710685 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310686
[email protected]49639fa2011-12-20 23:22:4110687 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310688
tfarina42834112016-09-22 13:38:2010689 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310691
10692 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110693 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310694
bnc691fda62016-08-12 00:43:1610695 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210696 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310697
maksim.sisove869bf52016-06-23 17:11:5210698 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310699
[email protected]dd3aa792013-07-16 19:10:2310700 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310701}
10702
bncd16676a2016-07-20 16:23:0110703TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510704 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210705 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610706 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810707 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10708 base::WriteFile(temp_file, temp_file_content.c_str(),
10709 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110710 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610711
danakj1fd259a02016-04-16 03:17:0910712 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910713 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410714 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710715 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210716 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710717
10718 HttpRequestInfo request;
10719 request.method = "POST";
bncce36dca22015-04-21 22:11:2310720 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710721 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010722 request.traffic_annotation =
10723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710724
[email protected]999dd8c2013-11-12 06:45:5410725 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610728
Ryan Sleevib8d7ea02018-05-07 20:01:0110729 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0710730 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610731
[email protected]49639fa2011-12-20 23:22:4110732 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610733
tfarina42834112016-09-22 13:38:2010734 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610736
10737 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110738 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610739
[email protected]dd3aa792013-07-16 19:10:2310740 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610741}
10742
bncd16676a2016-07-20 16:23:0110743TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310744 class FakeUploadElementReader : public UploadElementReader {
10745 public:
Chris Watkins7a41d3552017-12-01 02:13:2710746 FakeUploadElementReader() = default;
10747 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310748
Matt Menkecc1d3a902018-02-05 18:27:3310749 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310750
10751 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310752 int Init(CompletionOnceCallback callback) override {
10753 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310754 return ERR_IO_PENDING;
10755 }
avibf0746c2015-12-09 19:53:1410756 uint64_t GetContentLength() const override { return 0; }
10757 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010758 int Read(IOBuffer* buf,
10759 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310760 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310761 return ERR_FAILED;
10762 }
10763
10764 private:
Matt Menkecc1d3a902018-02-05 18:27:3310765 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310766 };
10767
10768 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910769 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10770 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210771 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310772
10773 HttpRequestInfo request;
10774 request.method = "POST";
bncce36dca22015-04-21 22:11:2310775 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310776 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010777 request.traffic_annotation =
10778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310779
danakj1fd259a02016-04-16 03:17:0910780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810781 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310783
10784 StaticSocketDataProvider data;
10785 session_deps_.socket_factory->AddSocketDataProvider(&data);
10786
10787 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010788 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510790 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310791
10792 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310793 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10794 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310795
10796 // Return Init()'s result after the transaction gets destroyed.
10797 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310798 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310799}
10800
[email protected]aeefc9e82010-02-19 16:18:2710801// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110802TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710803 HttpRequestInfo request;
10804 request.method = "GET";
bncce36dca22015-04-21 22:11:2310805 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010806 request.traffic_annotation =
10807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710808
10809 // First transaction will request a resource and receive a Basic challenge
10810 // with realm="first_realm".
10811 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310812 MockWrite(
10813 "GET / HTTP/1.1\r\n"
10814 "Host: www.example.org\r\n"
10815 "Connection: keep-alive\r\n"
10816 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710817 };
10818 MockRead data_reads1[] = {
10819 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10820 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10821 "\r\n"),
10822 };
10823
bnc691fda62016-08-12 00:43:1610824 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710825 // for first_realm. The server will reject and provide a challenge with
10826 // second_realm.
10827 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310828 MockWrite(
10829 "GET / HTTP/1.1\r\n"
10830 "Host: www.example.org\r\n"
10831 "Connection: keep-alive\r\n"
10832 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10833 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710834 };
10835 MockRead data_reads2[] = {
10836 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10837 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10838 "\r\n"),
10839 };
10840
10841 // This again fails, and goes back to first_realm. Make sure that the
10842 // entry is removed from cache.
10843 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310844 MockWrite(
10845 "GET / HTTP/1.1\r\n"
10846 "Host: www.example.org\r\n"
10847 "Connection: keep-alive\r\n"
10848 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10849 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710850 };
10851 MockRead data_reads3[] = {
10852 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10853 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10854 "\r\n"),
10855 };
10856
10857 // Try one last time (with the correct password) and get the resource.
10858 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310859 MockWrite(
10860 "GET / HTTP/1.1\r\n"
10861 "Host: www.example.org\r\n"
10862 "Connection: keep-alive\r\n"
10863 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10864 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710865 };
10866 MockRead data_reads4[] = {
10867 MockRead("HTTP/1.1 200 OK\r\n"
10868 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010869 "Content-Length: 5\r\n"
10870 "\r\n"
10871 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710872 };
10873
Ryan Sleevib8d7ea02018-05-07 20:01:0110874 StaticSocketDataProvider data1(data_reads1, data_writes1);
10875 StaticSocketDataProvider data2(data_reads2, data_writes2);
10876 StaticSocketDataProvider data3(data_reads3, data_writes3);
10877 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0710878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10879 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10880 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10881 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710882
[email protected]49639fa2011-12-20 23:22:4110883 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710884
danakj1fd259a02016-04-16 03:17:0910885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010887
[email protected]aeefc9e82010-02-19 16:18:2710888 // Issue the first request with Authorize headers. There should be a
10889 // password prompt for first_realm waiting to be filled in after the
10890 // transaction completes.
tfarina42834112016-09-22 13:38:2010891 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710893 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110894 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610895 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210896 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410897 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210898 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410899 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310900 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410901 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910902 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710903
10904 // Issue the second request with an incorrect password. There should be a
10905 // password prompt for second_realm waiting to be filled in after the
10906 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110907 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610908 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10909 callback2.callback());
robpercival214763f2016-07-01 23:27:0110910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710911 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110912 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610913 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210914 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410915 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210916 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410917 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310918 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410919 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910920 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710921
10922 // Issue the third request with another incorrect password. There should be
10923 // a password prompt for first_realm waiting to be filled in. If the password
10924 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10925 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110926 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610927 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10928 callback3.callback());
robpercival214763f2016-07-01 23:27:0110929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710930 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110931 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610932 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210933 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410934 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210935 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410936 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310937 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410938 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910939 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710940
10941 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110942 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610943 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10944 callback4.callback());
robpercival214763f2016-07-01 23:27:0110945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710946 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110947 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610948 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210949 ASSERT_TRUE(response);
10950 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710951}
10952
Bence Béky230ac612017-08-30 19:17:0810953// Regression test for https://crbug.com/754395.
10954TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10955 MockRead data_reads[] = {
10956 MockRead("HTTP/1.1 200 OK\r\n"),
10957 MockRead(kAlternativeServiceHttpHeader),
10958 MockRead("\r\n"),
10959 MockRead("hello world"),
10960 MockRead(SYNCHRONOUS, OK),
10961 };
10962
10963 HttpRequestInfo request;
10964 request.method = "GET";
10965 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010966 request.traffic_annotation =
10967 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0810968
Ryan Sleevib8d7ea02018-05-07 20:01:0110969 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0810970 session_deps_.socket_factory->AddSocketDataProvider(&data);
10971
10972 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910973 ssl.ssl_info.cert =
10974 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10975 ASSERT_TRUE(ssl.ssl_info.cert);
10976 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0810977 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10978
10979 TestCompletionCallback callback;
10980
10981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10983
10984 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10986
10987 url::SchemeHostPort test_server(request.url);
10988 HttpServerProperties* http_server_properties =
10989 session->http_server_properties();
10990 EXPECT_TRUE(
10991 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10992
10993 EXPECT_THAT(callback.WaitForResult(), IsOk());
10994
10995 const HttpResponseInfo* response = trans.GetResponseInfo();
10996 ASSERT_TRUE(response);
10997 ASSERT_TRUE(response->headers);
10998 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10999 EXPECT_FALSE(response->was_fetched_via_spdy);
11000 EXPECT_FALSE(response->was_alpn_negotiated);
11001
11002 std::string response_data;
11003 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11004 EXPECT_EQ("hello world", response_data);
11005
11006 EXPECT_TRUE(
11007 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11008}
11009
bncd16676a2016-07-20 16:23:0111010TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211011 MockRead data_reads[] = {
11012 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311013 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211014 MockRead("\r\n"),
11015 MockRead("hello world"),
11016 MockRead(SYNCHRONOUS, OK),
11017 };
11018
11019 HttpRequestInfo request;
11020 request.method = "GET";
bncb26024382016-06-29 02:39:4511021 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011022 request.traffic_annotation =
11023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211024
Ryan Sleevib8d7ea02018-05-07 20:01:0111025 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211026 session_deps_.socket_factory->AddSocketDataProvider(&data);
11027
bncb26024382016-06-29 02:39:4511028 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911029 ssl.ssl_info.cert =
11030 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11031 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11033
bncc958faa2015-07-31 18:14:5211034 TestCompletionCallback callback;
11035
danakj1fd259a02016-04-16 03:17:0911036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211038
tfarina42834112016-09-22 13:38:2011039 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211041
bncb26024382016-06-29 02:39:4511042 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011043 HttpServerProperties* http_server_properties =
11044 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411045 EXPECT_TRUE(
11046 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211047
robpercival214763f2016-07-01 23:27:0111048 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211049
bnc691fda62016-08-12 00:43:1611050 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211051 ASSERT_TRUE(response);
11052 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211053 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11054 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211055 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211056
11057 std::string response_data;
bnc691fda62016-08-12 00:43:1611058 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211059 EXPECT_EQ("hello world", response_data);
11060
zhongyic4de03032017-05-19 04:07:3411061 AlternativeServiceInfoVector alternative_service_info_vector =
11062 http_server_properties->GetAlternativeServiceInfos(test_server);
11063 ASSERT_EQ(1u, alternative_service_info_vector.size());
11064 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11065 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411066 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211067}
11068
bnce3dd56f2016-06-01 10:37:1111069// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111070TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111071 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111072 MockRead data_reads[] = {
11073 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311074 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111075 MockRead("\r\n"),
11076 MockRead("hello world"),
11077 MockRead(SYNCHRONOUS, OK),
11078 };
11079
11080 HttpRequestInfo request;
11081 request.method = "GET";
11082 request.url = GURL("http://www.example.org/");
11083 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011084 request.traffic_annotation =
11085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111086
Ryan Sleevib8d7ea02018-05-07 20:01:0111087 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111088 session_deps_.socket_factory->AddSocketDataProvider(&data);
11089
11090 TestCompletionCallback callback;
11091
11092 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611093 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111094
11095 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011096 HttpServerProperties* http_server_properties =
11097 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411098 EXPECT_TRUE(
11099 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111100
tfarina42834112016-09-22 13:38:2011101 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11103 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111104
bnc691fda62016-08-12 00:43:1611105 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111106 ASSERT_TRUE(response);
11107 ASSERT_TRUE(response->headers);
11108 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11109 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211110 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111111
11112 std::string response_data;
bnc691fda62016-08-12 00:43:1611113 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111114 EXPECT_EQ("hello world", response_data);
11115
zhongyic4de03032017-05-19 04:07:3411116 EXPECT_TRUE(
11117 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111118}
11119
bnca86731e2017-04-17 12:31:2811120// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511121// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111122TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511123 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811124 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511125
bnc8bef8da22016-05-30 01:28:2511126 HttpRequestInfo request;
11127 request.method = "GET";
bncb26024382016-06-29 02:39:4511128 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511129 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011130 request.traffic_annotation =
11131 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511132
11133 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11134 StaticSocketDataProvider first_data;
11135 first_data.set_connect_data(mock_connect);
11136 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511137 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611138 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511140
11141 MockRead data_reads[] = {
11142 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11143 MockRead(ASYNC, OK),
11144 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111145 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2511146 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11147
11148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11149
bnc525e175a2016-06-20 12:36:4011150 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511151 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111152 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11153 444);
bnc8bef8da22016-05-30 01:28:2511154 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111155 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511156 url::SchemeHostPort(request.url), alternative_service, expiration);
11157
bnc691fda62016-08-12 00:43:1611158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511159 TestCompletionCallback callback;
11160
tfarina42834112016-09-22 13:38:2011161 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511162 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111163 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511164}
11165
bnce3dd56f2016-06-01 10:37:1111166// Regression test for https://crbug.com/615497:
11167// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111168TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111169 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111170 HttpRequestInfo request;
11171 request.method = "GET";
11172 request.url = GURL("http://www.example.org/");
11173 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011174 request.traffic_annotation =
11175 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111176
11177 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11178 StaticSocketDataProvider first_data;
11179 first_data.set_connect_data(mock_connect);
11180 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11181
11182 MockRead data_reads[] = {
11183 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11184 MockRead(ASYNC, OK),
11185 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111186 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111187 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11188
11189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11190
bnc525e175a2016-06-20 12:36:4011191 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111192 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111193 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111194 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111195 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111196 url::SchemeHostPort(request.url), alternative_service, expiration);
11197
bnc691fda62016-08-12 00:43:1611198 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111199 TestCompletionCallback callback;
11200
tfarina42834112016-09-22 13:38:2011201 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111202 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111203 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111204}
11205
bncd16676a2016-07-20 16:23:0111206TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811207 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911208 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011209 HttpServerProperties* http_server_properties =
11210 session->http_server_properties();
bncb26024382016-06-29 02:39:4511211 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111212 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811213 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111214 http_server_properties->SetQuicAlternativeService(
11215 test_server, alternative_service, expiration,
11216 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411217 EXPECT_EQ(
11218 1u,
11219 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811220
11221 // Send a clear header.
11222 MockRead data_reads[] = {
11223 MockRead("HTTP/1.1 200 OK\r\n"),
11224 MockRead("Alt-Svc: clear\r\n"),
11225 MockRead("\r\n"),
11226 MockRead("hello world"),
11227 MockRead(SYNCHRONOUS, OK),
11228 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111229 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0811230 session_deps_.socket_factory->AddSocketDataProvider(&data);
11231
bncb26024382016-06-29 02:39:4511232 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911233 ssl.ssl_info.cert =
11234 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11235 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11237
bnc4f575852015-10-14 18:35:0811238 HttpRequestInfo request;
11239 request.method = "GET";
bncb26024382016-06-29 02:39:4511240 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011241 request.traffic_annotation =
11242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811243
11244 TestCompletionCallback callback;
11245
bnc691fda62016-08-12 00:43:1611246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811247
tfarina42834112016-09-22 13:38:2011248 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111249 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811250
bnc691fda62016-08-12 00:43:1611251 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211252 ASSERT_TRUE(response);
11253 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811254 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11255 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211256 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811257
11258 std::string response_data;
bnc691fda62016-08-12 00:43:1611259 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811260 EXPECT_EQ("hello world", response_data);
11261
zhongyic4de03032017-05-19 04:07:3411262 EXPECT_TRUE(
11263 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811264}
11265
bncd16676a2016-07-20 16:23:0111266TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211267 MockRead data_reads[] = {
11268 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311269 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11270 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211271 MockRead("hello world"),
11272 MockRead(SYNCHRONOUS, OK),
11273 };
11274
11275 HttpRequestInfo request;
11276 request.method = "GET";
bncb26024382016-06-29 02:39:4511277 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011278 request.traffic_annotation =
11279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211280
Ryan Sleevib8d7ea02018-05-07 20:01:0111281 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211282 session_deps_.socket_factory->AddSocketDataProvider(&data);
11283
bncb26024382016-06-29 02:39:4511284 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911285 ssl.ssl_info.cert =
11286 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11287 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11289
bncc958faa2015-07-31 18:14:5211290 TestCompletionCallback callback;
11291
danakj1fd259a02016-04-16 03:17:0911292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211294
tfarina42834112016-09-22 13:38:2011295 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211297
bncb26024382016-06-29 02:39:4511298 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011299 HttpServerProperties* http_server_properties =
11300 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411301 EXPECT_TRUE(
11302 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211303
robpercival214763f2016-07-01 23:27:0111304 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211305
bnc691fda62016-08-12 00:43:1611306 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211307 ASSERT_TRUE(response);
11308 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211309 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11310 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211311 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211312
11313 std::string response_data;
bnc691fda62016-08-12 00:43:1611314 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211315 EXPECT_EQ("hello world", response_data);
11316
zhongyic4de03032017-05-19 04:07:3411317 AlternativeServiceInfoVector alternative_service_info_vector =
11318 http_server_properties->GetAlternativeServiceInfos(test_server);
11319 ASSERT_EQ(2u, alternative_service_info_vector.size());
11320
11321 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11322 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411323 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411324 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11325 1234);
11326 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411327 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211328}
11329
bncd16676a2016-07-20 16:23:0111330TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611331 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211332 HostPortPair alternative("alternative.example.org", 443);
11333 std::string origin_url = "https://origin.example.org:443";
11334 std::string alternative_url = "https://alternative.example.org:443";
11335
11336 // Negotiate HTTP/1.1 with alternative.example.org.
11337 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611338 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11340
11341 // HTTP/1.1 data for request.
11342 MockWrite http_writes[] = {
11343 MockWrite("GET / HTTP/1.1\r\n"
11344 "Host: alternative.example.org\r\n"
11345 "Connection: keep-alive\r\n\r\n"),
11346 };
11347
11348 MockRead http_reads[] = {
11349 MockRead("HTTP/1.1 200 OK\r\n"
11350 "Content-Type: text/html; charset=iso-8859-1\r\n"
11351 "Content-Length: 40\r\n\r\n"
11352 "first HTTP/1.1 response from alternative"),
11353 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111354 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211355 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11356
11357 StaticSocketDataProvider data_refused;
11358 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11359 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11360
zhongyi3d4a55e72016-04-22 20:36:4611361 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011363 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211364 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111365 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211366 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111367 http_server_properties->SetQuicAlternativeService(
11368 server, alternative_service, expiration,
11369 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211370 // Mark the QUIC alternative service as broken.
11371 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11372
zhongyi48704c182015-12-07 07:52:0211373 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211375 request.method = "GET";
11376 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011377 request.traffic_annotation =
11378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11379
zhongyi48704c182015-12-07 07:52:0211380 TestCompletionCallback callback;
11381 NetErrorDetails details;
11382 EXPECT_FALSE(details.quic_broken);
11383
tfarina42834112016-09-22 13:38:2011384 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611385 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211386 EXPECT_TRUE(details.quic_broken);
11387}
11388
bncd16676a2016-07-20 16:23:0111389TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611390 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211391 HostPortPair alternative1("alternative1.example.org", 443);
11392 HostPortPair alternative2("alternative2.example.org", 443);
11393 std::string origin_url = "https://origin.example.org:443";
11394 std::string alternative_url1 = "https://alternative1.example.org:443";
11395 std::string alternative_url2 = "https://alternative2.example.org:443";
11396
11397 // Negotiate HTTP/1.1 with alternative1.example.org.
11398 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611399 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211400 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11401
11402 // HTTP/1.1 data for request.
11403 MockWrite http_writes[] = {
11404 MockWrite("GET / HTTP/1.1\r\n"
11405 "Host: alternative1.example.org\r\n"
11406 "Connection: keep-alive\r\n\r\n"),
11407 };
11408
11409 MockRead http_reads[] = {
11410 MockRead("HTTP/1.1 200 OK\r\n"
11411 "Content-Type: text/html; charset=iso-8859-1\r\n"
11412 "Content-Length: 40\r\n\r\n"
11413 "first HTTP/1.1 response from alternative1"),
11414 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111415 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211416 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11417
11418 StaticSocketDataProvider data_refused;
11419 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11420 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11421
danakj1fd259a02016-04-16 03:17:0911422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011423 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211424 session->http_server_properties();
11425
zhongyi3d4a55e72016-04-22 20:36:4611426 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211427 AlternativeServiceInfoVector alternative_service_info_vector;
11428 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11429
bnc3472afd2016-11-17 15:27:2111430 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111431 alternative_service_info_vector.push_back(
11432 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11433 alternative_service1, expiration,
11434 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111435 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111436 alternative_service_info_vector.push_back(
11437 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11438 alternative_service2, expiration,
11439 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211440
11441 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611442 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211443
11444 // Mark one of the QUIC alternative service as broken.
11445 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411446 EXPECT_EQ(2u,
11447 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211448
zhongyi48704c182015-12-07 07:52:0211449 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211451 request.method = "GET";
11452 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011453 request.traffic_annotation =
11454 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11455
zhongyi48704c182015-12-07 07:52:0211456 TestCompletionCallback callback;
11457 NetErrorDetails details;
11458 EXPECT_FALSE(details.quic_broken);
11459
tfarina42834112016-09-22 13:38:2011460 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611461 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211462 EXPECT_FALSE(details.quic_broken);
11463}
11464
bncd16676a2016-07-20 16:23:0111465TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211466 HttpRequestInfo request;
11467 request.method = "GET";
bncb26024382016-06-29 02:39:4511468 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011469 request.traffic_annotation =
11470 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211471
[email protected]d973e99a2012-02-17 21:02:3611472 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211473 StaticSocketDataProvider first_data;
11474 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711475 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511476 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611477 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211479
11480 MockRead data_reads[] = {
11481 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11482 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611483 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211484 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111485 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711486 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211487
danakj1fd259a02016-04-16 03:17:0911488 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211489
bnc525e175a2016-06-20 12:36:4011490 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311491 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611492 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111493 // Port must be < 1024, or the header will be ignored (since initial port was
11494 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111495 // Port is ignored by MockConnect anyway.
11496 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11497 666);
bnc7dc7e1b42015-07-28 14:43:1211498 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111499 http_server_properties->SetHttp2AlternativeService(
11500 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211501
bnc691fda62016-08-12 00:43:1611502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111503 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211504
tfarina42834112016-09-22 13:38:2011505 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11507 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211508
bnc691fda62016-08-12 00:43:1611509 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211510 ASSERT_TRUE(response);
11511 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211512 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11513
11514 std::string response_data;
bnc691fda62016-08-12 00:43:1611515 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211516 EXPECT_EQ("hello world", response_data);
11517
zhongyic4de03032017-05-19 04:07:3411518 const AlternativeServiceInfoVector alternative_service_info_vector =
11519 http_server_properties->GetAlternativeServiceInfos(server);
11520 ASSERT_EQ(1u, alternative_service_info_vector.size());
11521 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411522 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411523 EXPECT_TRUE(
11524 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211525}
11526
bnc55ff9da2015-08-19 18:42:3511527// Ensure that we are not allowed to redirect traffic via an alternate protocol
11528// to an unrestricted (port >= 1024) when the original traffic was on a
11529// restricted port (port < 1024). Ensure that we can redirect in all other
11530// cases.
bncd16676a2016-07-20 16:23:0111531TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111532 HttpRequestInfo restricted_port_request;
11533 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511534 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111535 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011536 restricted_port_request.traffic_annotation =
11537 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111538
[email protected]d973e99a2012-02-17 21:02:3611539 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111540 StaticSocketDataProvider first_data;
11541 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711542 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111543
11544 MockRead data_reads[] = {
11545 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11546 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611547 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111548 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111549 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711550 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511551 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611552 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511553 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111554
danakj1fd259a02016-04-16 03:17:0911555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111556
bnc525e175a2016-06-20 12:36:4011557 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311558 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111559 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111560 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11561 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211562 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111563 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611564 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011565 expiration);
[email protected]3912662a32011-10-04 00:51:1111566
bnc691fda62016-08-12 00:43:1611567 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111568 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111569
tfarina42834112016-09-22 13:38:2011570 int rv = trans.Start(&restricted_port_request, callback.callback(),
11571 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111573 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111574 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911575}
[email protected]3912662a32011-10-04 00:51:1111576
bnc55ff9da2015-08-19 18:42:3511577// Ensure that we are allowed to redirect traffic via an alternate protocol to
11578// an unrestricted (port >= 1024) when the original traffic was on a restricted
11579// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111580TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711581 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911582
11583 HttpRequestInfo restricted_port_request;
11584 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511585 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911586 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011587 restricted_port_request.traffic_annotation =
11588 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911589
11590 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11591 StaticSocketDataProvider first_data;
11592 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711593 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911594
11595 MockRead data_reads[] = {
11596 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11597 MockRead("hello world"),
11598 MockRead(ASYNC, OK),
11599 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111600 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711601 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511602 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611603 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511604 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911605
danakj1fd259a02016-04-16 03:17:0911606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911607
bnc525e175a2016-06-20 12:36:4011608 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911609 session->http_server_properties();
11610 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111611 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11612 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211613 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111614 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611615 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011616 expiration);
[email protected]c54c6962013-02-01 04:53:1911617
bnc691fda62016-08-12 00:43:1611618 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911619 TestCompletionCallback callback;
11620
tfarina42834112016-09-22 13:38:2011621 EXPECT_EQ(ERR_IO_PENDING,
11622 trans.Start(&restricted_port_request, callback.callback(),
11623 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911624 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111625 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111626}
11627
bnc55ff9da2015-08-19 18:42:3511628// Ensure that we are not allowed to redirect traffic via an alternate protocol
11629// to an unrestricted (port >= 1024) when the original traffic was on a
11630// restricted port (port < 1024). Ensure that we can redirect in all other
11631// cases.
bncd16676a2016-07-20 16:23:0111632TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111633 HttpRequestInfo restricted_port_request;
11634 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511635 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111636 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011637 restricted_port_request.traffic_annotation =
11638 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111639
[email protected]d973e99a2012-02-17 21:02:3611640 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111641 StaticSocketDataProvider first_data;
11642 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711643 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111644
11645 MockRead data_reads[] = {
11646 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11647 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611648 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111649 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111650 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711651 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111652
bncb26024382016-06-29 02:39:4511653 SSLSocketDataProvider ssl(ASYNC, OK);
11654 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11655
danakj1fd259a02016-04-16 03:17:0911656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111657
bnc525e175a2016-06-20 12:36:4011658 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311659 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111660 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111661 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11662 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211663 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111664 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611665 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011666 expiration);
[email protected]3912662a32011-10-04 00:51:1111667
bnc691fda62016-08-12 00:43:1611668 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111669 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111670
tfarina42834112016-09-22 13:38:2011671 int rv = trans.Start(&restricted_port_request, callback.callback(),
11672 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111674 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111675 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111676}
11677
bnc55ff9da2015-08-19 18:42:3511678// Ensure that we are not allowed to redirect traffic via an alternate protocol
11679// to an unrestricted (port >= 1024) when the original traffic was on a
11680// restricted port (port < 1024). Ensure that we can redirect in all other
11681// cases.
bncd16676a2016-07-20 16:23:0111682TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111683 HttpRequestInfo unrestricted_port_request;
11684 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511685 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111686 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011687 unrestricted_port_request.traffic_annotation =
11688 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111689
[email protected]d973e99a2012-02-17 21:02:3611690 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111691 StaticSocketDataProvider first_data;
11692 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711693 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111694
11695 MockRead data_reads[] = {
11696 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11697 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611698 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111699 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111700 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711701 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511702 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611703 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511704 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111705
danakj1fd259a02016-04-16 03:17:0911706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111707
bnc525e175a2016-06-20 12:36:4011708 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311709 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111710 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111711 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11712 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211713 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111714 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611715 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011716 expiration);
[email protected]3912662a32011-10-04 00:51:1111717
bnc691fda62016-08-12 00:43:1611718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111719 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111720
bnc691fda62016-08-12 00:43:1611721 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011722 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111724 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111725 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111726}
11727
bnc55ff9da2015-08-19 18:42:3511728// Ensure that we are not allowed to redirect traffic via an alternate protocol
11729// to an unrestricted (port >= 1024) when the original traffic was on a
11730// restricted port (port < 1024). Ensure that we can redirect in all other
11731// cases.
bncd16676a2016-07-20 16:23:0111732TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111733 HttpRequestInfo unrestricted_port_request;
11734 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511735 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111736 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011737 unrestricted_port_request.traffic_annotation =
11738 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111739
[email protected]d973e99a2012-02-17 21:02:3611740 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111741 StaticSocketDataProvider first_data;
11742 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711743 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111744
11745 MockRead data_reads[] = {
11746 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11747 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611748 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111749 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111750 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711751 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111752
bncb26024382016-06-29 02:39:4511753 SSLSocketDataProvider ssl(ASYNC, OK);
11754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11755
danakj1fd259a02016-04-16 03:17:0911756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111757
bnc525e175a2016-06-20 12:36:4011758 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311759 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211760 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111761 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11762 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211763 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111764 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611765 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011766 expiration);
[email protected]3912662a32011-10-04 00:51:1111767
bnc691fda62016-08-12 00:43:1611768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111769 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111770
bnc691fda62016-08-12 00:43:1611771 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011772 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111774 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111775 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111776}
11777
bnc55ff9da2015-08-19 18:42:3511778// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2111779// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
11780// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111781TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211782 HttpRequestInfo request;
11783 request.method = "GET";
bncce36dca22015-04-21 22:11:2311784 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011785 request.traffic_annotation =
11786 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211787
11788 // The alternate protocol request will error out before we attempt to connect,
11789 // so only the standard HTTP request will try to connect.
11790 MockRead data_reads[] = {
11791 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11792 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611793 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211794 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111795 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711796 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211797
danakj1fd259a02016-04-16 03:17:0911798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211799
bnc525e175a2016-06-20 12:36:4011800 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211801 session->http_server_properties();
11802 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111803 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11804 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211805 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111806 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611807 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211808
bnc691fda62016-08-12 00:43:1611809 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211810 TestCompletionCallback callback;
11811
tfarina42834112016-09-22 13:38:2011812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211814 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111815 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211816
bnc691fda62016-08-12 00:43:1611817 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211818 ASSERT_TRUE(response);
11819 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211820 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11821
11822 std::string response_data;
bnc691fda62016-08-12 00:43:1611823 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211824 EXPECT_EQ("hello world", response_data);
11825}
11826
bncd16676a2016-07-20 16:23:0111827TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411828 HttpRequestInfo request;
11829 request.method = "GET";
bncb26024382016-06-29 02:39:4511830 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011831 request.traffic_annotation =
11832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411833
11834 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211835 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311836 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211837 MockRead("\r\n"),
11838 MockRead("hello world"),
11839 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11840 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411841
Ryan Sleevib8d7ea02018-05-07 20:01:0111842 StaticSocketDataProvider first_transaction(data_reads,
11843 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711844 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511845 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611846 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511847 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411848
bnc032658ba2016-09-26 18:17:1511849 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411850
bncdf80d44fd2016-07-15 20:27:4111851 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511852 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111853 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411854
bnc42331402016-07-25 13:36:1511855 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111856 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411857 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111858 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411859 };
11860
Ryan Sleevib8d7ea02018-05-07 20:01:0111861 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0711862 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411863
[email protected]d973e99a2012-02-17 21:02:3611864 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111865 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5511866 hanging_non_alternate_protocol_socket.set_connect_data(
11867 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711868 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511869 &hanging_non_alternate_protocol_socket);
11870
[email protected]49639fa2011-12-20 23:22:4111871 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411872
danakj1fd259a02016-04-16 03:17:0911873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811874 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411876
tfarina42834112016-09-22 13:38:2011877 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11879 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411880
11881 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211882 ASSERT_TRUE(response);
11883 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411884 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11885
11886 std::string response_data;
robpercival214763f2016-07-01 23:27:0111887 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411888 EXPECT_EQ("hello world", response_data);
11889
bnc87dcefc2017-05-25 12:47:5811890 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911891 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411892
tfarina42834112016-09-22 13:38:2011893 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11895 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411896
11897 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211898 ASSERT_TRUE(response);
11899 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211900 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311901 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211902 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411903
robpercival214763f2016-07-01 23:27:0111904 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411905 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411906}
11907
bncd16676a2016-07-20 16:23:0111908TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511909 HttpRequestInfo request;
11910 request.method = "GET";
bncb26024382016-06-29 02:39:4511911 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011912 request.traffic_annotation =
11913 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511914
bncb26024382016-06-29 02:39:4511915 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511916 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211917 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311918 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211919 MockRead("\r\n"),
11920 MockRead("hello world"),
11921 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11922 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511923 };
11924
Ryan Sleevib8d7ea02018-05-07 20:01:0111925 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4511926 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511927
bncb26024382016-06-29 02:39:4511928 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911929 ssl_http11.ssl_info.cert =
11930 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11931 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511932 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11933
11934 // Second transaction starts an alternative and a non-alternative Job.
11935 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611936 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111937 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1811938 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811939 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11940
Ryan Sleevib8d7ea02018-05-07 20:01:0111941 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1811942 hanging_socket2.set_connect_data(never_finishing_connect);
11943 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511944
bncb26024382016-06-29 02:39:4511945 // Third transaction starts an alternative and a non-alternative job.
11946 // The non-alternative job hangs, but the alternative one succeeds.
11947 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111948 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511949 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111950 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511951 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511952 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111953 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511954 };
bnc42331402016-07-25 13:36:1511955 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111956 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511957 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111958 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511959 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111960 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11961 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311962 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511963 };
11964
Ryan Sleevib8d7ea02018-05-07 20:01:0111965 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0711966 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511967
bnc032658ba2016-09-26 18:17:1511968 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511969
Ryan Sleevib8d7ea02018-05-07 20:01:0111970 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1811971 hanging_socket3.set_connect_data(never_finishing_connect);
11972 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511973
danakj1fd259a02016-04-16 03:17:0911974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111975 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011976 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511977
tfarina42834112016-09-22 13:38:2011978 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11980 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511981
11982 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211983 ASSERT_TRUE(response);
11984 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511985 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11986
11987 std::string response_data;
robpercival214763f2016-07-01 23:27:0111988 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511989 EXPECT_EQ("hello world", response_data);
11990
[email protected]49639fa2011-12-20 23:22:4111991 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011992 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011993 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511995
[email protected]49639fa2011-12-20 23:22:4111996 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011997 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011998 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512000
robpercival214763f2016-07-01 23:27:0112001 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12002 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512003
12004 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212005 ASSERT_TRUE(response);
12006 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212007 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512008 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212009 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112010 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512011 EXPECT_EQ("hello!", response_data);
12012
12013 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212014 ASSERT_TRUE(response);
12015 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212016 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512017 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212018 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112019 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512020 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512021}
12022
bncd16676a2016-07-20 16:23:0112023TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512024 HttpRequestInfo request;
12025 request.method = "GET";
bncb26024382016-06-29 02:39:4512026 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012027 request.traffic_annotation =
12028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512029
12030 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212031 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312032 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212033 MockRead("\r\n"),
12034 MockRead("hello world"),
12035 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12036 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512037 };
12038
Ryan Sleevib8d7ea02018-05-07 20:01:0112039 StaticSocketDataProvider first_transaction(data_reads,
12040 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712041 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512042
[email protected]8ddf8322012-02-23 18:08:0612043 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912044 ssl.ssl_info.cert =
12045 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12046 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712047 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512048
[email protected]d973e99a2012-02-17 21:02:3612049 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112050 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512051 hanging_alternate_protocol_socket.set_connect_data(
12052 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712053 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512054 &hanging_alternate_protocol_socket);
12055
bncb26024382016-06-29 02:39:4512056 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112057 StaticSocketDataProvider second_transaction(data_reads,
12058 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812059 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512061
[email protected]49639fa2011-12-20 23:22:4112062 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512063
danakj1fd259a02016-04-16 03:17:0912064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812065 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912066 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512067
tfarina42834112016-09-22 13:38:2012068 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12070 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512071
12072 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212073 ASSERT_TRUE(response);
12074 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512075 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12076
12077 std::string response_data;
robpercival214763f2016-07-01 23:27:0112078 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512079 EXPECT_EQ("hello world", response_data);
12080
bnc87dcefc2017-05-25 12:47:5812081 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912082 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512083
tfarina42834112016-09-22 13:38:2012084 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12086 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512087
12088 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212089 ASSERT_TRUE(response);
12090 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512091 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12092 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212093 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512094
robpercival214763f2016-07-01 23:27:0112095 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512096 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512097}
12098
[email protected]631f1322010-04-30 17:59:1112099class CapturingProxyResolver : public ProxyResolver {
12100 public:
Chris Watkins7a41d3552017-12-01 02:13:2712101 CapturingProxyResolver() = default;
12102 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112103
dchengb03027d2014-10-21 12:00:2012104 int GetProxyForURL(const GURL& url,
12105 ProxyInfo* results,
12106 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512107 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012108 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012109 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12110 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212111 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112112 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212113 return OK;
[email protected]631f1322010-04-30 17:59:1112114 }
12115
[email protected]24476402010-07-20 20:55:1712116 const std::vector<GURL>& resolved() const { return resolved_; }
12117
12118 private:
[email protected]631f1322010-04-30 17:59:1112119 std::vector<GURL> resolved_;
12120
12121 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12122};
12123
sammce64b2362015-04-29 03:50:2312124class CapturingProxyResolverFactory : public ProxyResolverFactory {
12125 public:
12126 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12127 : ProxyResolverFactory(false), resolver_(resolver) {}
12128
Lily Houghton99597862018-03-07 16:40:4212129 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12130 std::unique_ptr<ProxyResolver>* resolver,
12131 const net::CompletionCallback& callback,
12132 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912133 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312134 return OK;
12135 }
12136
12137 private:
12138 ProxyResolver* resolver_;
12139};
12140
bnc2e884782016-08-11 19:45:1912141// Test that proxy is resolved using the origin url,
12142// regardless of the alternative server.
12143TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12144 // Configure proxy to bypass www.example.org, which is the origin URL.
12145 ProxyConfig proxy_config;
12146 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12147 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912148 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12149 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912150
12151 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912152 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912153 &capturing_proxy_resolver);
12154
12155 TestNetLog net_log;
12156
Bence Béky53a5aef2018-03-29 21:54:1212157 session_deps_.proxy_resolution_service =
12158 std::make_unique<ProxyResolutionService>(
12159 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12160 &net_log);
bnc2e884782016-08-11 19:45:1912161
12162 session_deps_.net_log = &net_log;
12163
12164 // Configure alternative service with a hostname that is not bypassed by the
12165 // proxy.
12166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12167 HttpServerProperties* http_server_properties =
12168 session->http_server_properties();
12169 url::SchemeHostPort server("https", "www.example.org", 443);
12170 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112171 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912172 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112173 http_server_properties->SetHttp2AlternativeService(
12174 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912175
12176 // Non-alternative job should hang.
12177 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112178 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1912179 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12180 session_deps_.socket_factory->AddSocketDataProvider(
12181 &hanging_alternate_protocol_socket);
12182
bnc032658ba2016-09-26 18:17:1512183 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912184
12185 HttpRequestInfo request;
12186 request.method = "GET";
12187 request.url = GURL("https://www.example.org/");
12188 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012189 request.traffic_annotation =
12190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912191
12192 SpdySerializedFrame req(
12193 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12194
12195 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12196
12197 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12198 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12199 MockRead spdy_reads[] = {
12200 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12201 };
12202
Ryan Sleevib8d7ea02018-05-07 20:01:0112203 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1912204 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12205
12206 TestCompletionCallback callback;
12207
12208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12209
tfarina42834112016-09-22 13:38:2012210 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912211 EXPECT_THAT(callback.GetResult(rv), IsOk());
12212
12213 const HttpResponseInfo* response = trans.GetResponseInfo();
12214 ASSERT_TRUE(response);
12215 ASSERT_TRUE(response->headers);
12216 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12217 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212218 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912219
12220 std::string response_data;
12221 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12222 EXPECT_EQ("hello!", response_data);
12223
12224 // Origin host bypasses proxy, no resolution should have happened.
12225 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12226}
12227
bncd16676a2016-07-20 16:23:0112228TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112229 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212230 proxy_config.set_auto_detect(true);
12231 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112232
sammc5dd160c2015-04-02 02:43:1312233 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912234 session_deps_.proxy_resolution_service =
12235 std::make_unique<ProxyResolutionService>(
12236 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12237 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12238 std::make_unique<CapturingProxyResolverFactory>(
12239 &capturing_proxy_resolver),
12240 nullptr);
vishal.b62985ca92015-04-17 08:45:5112241 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712242 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112243
12244 HttpRequestInfo request;
12245 request.method = "GET";
bncb26024382016-06-29 02:39:4512246 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012247 request.traffic_annotation =
12248 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112249
12250 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212251 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312252 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212253 MockRead("\r\n"),
12254 MockRead("hello world"),
12255 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12256 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112257 };
12258
Ryan Sleevib8d7ea02018-05-07 20:01:0112259 StaticSocketDataProvider first_transaction(data_reads,
12260 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712261 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512262 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612263 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112265
bnc032658ba2016-09-26 18:17:1512266 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112267
bncdf80d44fd2016-07-15 20:27:4112268 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512269 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112270 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312271 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512272 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12273 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312274 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112275 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112276 };
12277
[email protected]d911f1b2010-05-05 22:39:4212278 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12279
bnc42331402016-07-25 13:36:1512280 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112281 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112282 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112283 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12284 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112285 };
12286
Ryan Sleevib8d7ea02018-05-07 20:01:0112287 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712288 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112289
[email protected]d973e99a2012-02-17 21:02:3612290 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112291 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512292 hanging_non_alternate_protocol_socket.set_connect_data(
12293 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712294 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512295 &hanging_non_alternate_protocol_socket);
12296
[email protected]49639fa2011-12-20 23:22:4112297 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112298
danakj1fd259a02016-04-16 03:17:0912299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812300 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912301 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112302
tfarina42834112016-09-22 13:38:2012303 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12305 EXPECT_THAT(callback.WaitForResult(), IsOk());
12306
12307 const HttpResponseInfo* response = trans->GetResponseInfo();
12308 ASSERT_TRUE(response);
12309 ASSERT_TRUE(response->headers);
12310 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12311 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212312 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112313
12314 std::string response_data;
12315 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12316 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112317
bnc87dcefc2017-05-25 12:47:5812318 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912319 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112320
tfarina42834112016-09-22 13:38:2012321 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12323 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112324
mmenkea2dcd3bf2016-08-16 21:49:4112325 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212326 ASSERT_TRUE(response);
12327 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212328 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312329 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212330 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112331
robpercival214763f2016-07-01 23:27:0112332 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112333 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512334 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12335 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312336 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312337 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312338 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112339
[email protected]029c83b62013-01-24 05:28:2012340 LoadTimingInfo load_timing_info;
12341 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12342 TestLoadTimingNotReusedWithPac(load_timing_info,
12343 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112344}
[email protected]631f1322010-04-30 17:59:1112345
bncd16676a2016-07-20 16:23:0112346TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812347 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412348 HttpRequestInfo request;
12349 request.method = "GET";
bncb26024382016-06-29 02:39:4512350 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012351 request.traffic_annotation =
12352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412353
12354 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212355 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312356 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212357 MockRead("\r\n"),
12358 MockRead("hello world"),
12359 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412360 };
12361
Ryan Sleevib8d7ea02018-05-07 20:01:0112362 StaticSocketDataProvider first_transaction(data_reads,
12363 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712364 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512365 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612366 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412368
bnc032658ba2016-09-26 18:17:1512369 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412370
bncdf80d44fd2016-07-15 20:27:4112371 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512372 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112373 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412374
bnc42331402016-07-25 13:36:1512375 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112376 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412377 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112378 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412379 };
12380
Ryan Sleevib8d7ea02018-05-07 20:01:0112381 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712382 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412383
[email protected]83039bb2011-12-09 18:43:5512384 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412385
danakj1fd259a02016-04-16 03:17:0912386 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412387
bnc87dcefc2017-05-25 12:47:5812388 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912389 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412390
tfarina42834112016-09-22 13:38:2012391 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12393 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412394
12395 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212396 ASSERT_TRUE(response);
12397 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412398 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12399
12400 std::string response_data;
robpercival214763f2016-07-01 23:27:0112401 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412402 EXPECT_EQ("hello world", response_data);
12403
12404 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512405 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012406 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412407 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712408 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212409 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812410
bnc87dcefc2017-05-25 12:47:5812411 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912412 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412413
tfarina42834112016-09-22 13:38:2012414 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12416 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412417
12418 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212419 ASSERT_TRUE(response);
12420 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212421 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312422 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212423 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412424
robpercival214763f2016-07-01 23:27:0112425 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412426 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212427}
12428
[email protected]044de0642010-06-17 10:42:1512429// GenerateAuthToken is a mighty big test.
12430// It tests all permutation of GenerateAuthToken behavior:
12431// - Synchronous and Asynchronous completion.
12432// - OK or error on completion.
12433// - Direct connection, non-authenticating proxy, and authenticating proxy.
12434// - HTTP or HTTPS backend (to include proxy tunneling).
12435// - Non-authenticating and authenticating backend.
12436//
[email protected]fe3b7dc2012-02-03 19:52:0912437// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512438// problems generating an auth token for an authenticating proxy, we don't
12439// need to test all permutations of the backend server).
12440//
12441// The test proceeds by going over each of the configuration cases, and
12442// potentially running up to three rounds in each of the tests. The TestConfig
12443// specifies both the configuration for the test as well as the expectations
12444// for the results.
bncd16676a2016-07-20 16:23:0112445TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012446 static const char kServer[] = "http://www.example.com";
12447 static const char kSecureServer[] = "https://www.example.com";
12448 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512449
12450 enum AuthTiming {
12451 AUTH_NONE,
12452 AUTH_SYNC,
12453 AUTH_ASYNC,
12454 };
12455
12456 const MockWrite kGet(
12457 "GET / HTTP/1.1\r\n"
12458 "Host: www.example.com\r\n"
12459 "Connection: keep-alive\r\n\r\n");
12460 const MockWrite kGetProxy(
12461 "GET http://www.example.com/ HTTP/1.1\r\n"
12462 "Host: www.example.com\r\n"
12463 "Proxy-Connection: keep-alive\r\n\r\n");
12464 const MockWrite kGetAuth(
12465 "GET / HTTP/1.1\r\n"
12466 "Host: www.example.com\r\n"
12467 "Connection: keep-alive\r\n"
12468 "Authorization: auth_token\r\n\r\n");
12469 const MockWrite kGetProxyAuth(
12470 "GET http://www.example.com/ HTTP/1.1\r\n"
12471 "Host: www.example.com\r\n"
12472 "Proxy-Connection: keep-alive\r\n"
12473 "Proxy-Authorization: auth_token\r\n\r\n");
12474 const MockWrite kGetAuthThroughProxy(
12475 "GET http://www.example.com/ HTTP/1.1\r\n"
12476 "Host: www.example.com\r\n"
12477 "Proxy-Connection: keep-alive\r\n"
12478 "Authorization: auth_token\r\n\r\n");
12479 const MockWrite kGetAuthWithProxyAuth(
12480 "GET http://www.example.com/ HTTP/1.1\r\n"
12481 "Host: www.example.com\r\n"
12482 "Proxy-Connection: keep-alive\r\n"
12483 "Proxy-Authorization: auth_token\r\n"
12484 "Authorization: auth_token\r\n\r\n");
12485 const MockWrite kConnect(
12486 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712487 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512488 "Proxy-Connection: keep-alive\r\n\r\n");
12489 const MockWrite kConnectProxyAuth(
12490 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712491 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512492 "Proxy-Connection: keep-alive\r\n"
12493 "Proxy-Authorization: auth_token\r\n\r\n");
12494
12495 const MockRead kSuccess(
12496 "HTTP/1.1 200 OK\r\n"
12497 "Content-Type: text/html; charset=iso-8859-1\r\n"
12498 "Content-Length: 3\r\n\r\n"
12499 "Yes");
12500 const MockRead kFailure(
12501 "Should not be called.");
12502 const MockRead kServerChallenge(
12503 "HTTP/1.1 401 Unauthorized\r\n"
12504 "WWW-Authenticate: Mock realm=server\r\n"
12505 "Content-Type: text/html; charset=iso-8859-1\r\n"
12506 "Content-Length: 14\r\n\r\n"
12507 "Unauthorized\r\n");
12508 const MockRead kProxyChallenge(
12509 "HTTP/1.1 407 Unauthorized\r\n"
12510 "Proxy-Authenticate: Mock realm=proxy\r\n"
12511 "Proxy-Connection: close\r\n"
12512 "Content-Type: text/html; charset=iso-8859-1\r\n"
12513 "Content-Length: 14\r\n\r\n"
12514 "Unauthorized\r\n");
12515 const MockRead kProxyConnected(
12516 "HTTP/1.1 200 Connection Established\r\n\r\n");
12517
12518 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12519 // no constructors, but the C++ compiler on Windows warns about
12520 // unspecified data in compound literals. So, moved to using constructors,
12521 // and TestRound's created with the default constructor should not be used.
12522 struct TestRound {
12523 TestRound()
12524 : expected_rv(ERR_UNEXPECTED),
12525 extra_write(NULL),
12526 extra_read(NULL) {
12527 }
12528 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12529 int expected_rv_arg)
12530 : write(write_arg),
12531 read(read_arg),
12532 expected_rv(expected_rv_arg),
12533 extra_write(NULL),
12534 extra_read(NULL) {
12535 }
12536 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12537 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112538 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512539 : write(write_arg),
12540 read(read_arg),
12541 expected_rv(expected_rv_arg),
12542 extra_write(extra_write_arg),
12543 extra_read(extra_read_arg) {
12544 }
12545 MockWrite write;
12546 MockRead read;
12547 int expected_rv;
12548 const MockWrite* extra_write;
12549 const MockRead* extra_read;
12550 };
12551
12552 static const int kNoSSL = 500;
12553
12554 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112555 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112556 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512557 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112558 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112559 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512560 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112561 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512562 int num_auth_rounds;
12563 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612564 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512565 } test_configs[] = {
asankac93076192016-10-03 15:46:0212566 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112567 {__LINE__,
12568 nullptr,
asankac93076192016-10-03 15:46:0212569 AUTH_NONE,
12570 OK,
12571 kServer,
12572 AUTH_NONE,
12573 OK,
12574 1,
12575 kNoSSL,
12576 {TestRound(kGet, kSuccess, OK)}},
12577 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112578 {__LINE__,
12579 nullptr,
asankac93076192016-10-03 15:46:0212580 AUTH_NONE,
12581 OK,
12582 kServer,
12583 AUTH_SYNC,
12584 OK,
12585 2,
12586 kNoSSL,
12587 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512588 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112589 {__LINE__,
12590 nullptr,
asankac93076192016-10-03 15:46:0212591 AUTH_NONE,
12592 OK,
12593 kServer,
12594 AUTH_SYNC,
12595 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612596 3,
12597 kNoSSL,
12598 {TestRound(kGet, kServerChallenge, OK),
12599 TestRound(kGet, kServerChallenge, OK),
12600 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112601 {__LINE__,
12602 nullptr,
asankae2257db2016-10-11 22:03:1612603 AUTH_NONE,
12604 OK,
12605 kServer,
12606 AUTH_SYNC,
12607 ERR_UNSUPPORTED_AUTH_SCHEME,
12608 2,
12609 kNoSSL,
12610 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112611 {__LINE__,
12612 nullptr,
asankae2257db2016-10-11 22:03:1612613 AUTH_NONE,
12614 OK,
12615 kServer,
12616 AUTH_SYNC,
12617 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12618 2,
12619 kNoSSL,
12620 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112621 {__LINE__,
12622 kProxy,
asankae2257db2016-10-11 22:03:1612623 AUTH_SYNC,
12624 ERR_FAILED,
12625 kServer,
12626 AUTH_NONE,
12627 OK,
12628 2,
12629 kNoSSL,
12630 {TestRound(kGetProxy, kProxyChallenge, OK),
12631 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112632 {__LINE__,
12633 kProxy,
asankae2257db2016-10-11 22:03:1612634 AUTH_ASYNC,
12635 ERR_FAILED,
12636 kServer,
12637 AUTH_NONE,
12638 OK,
12639 2,
12640 kNoSSL,
12641 {TestRound(kGetProxy, kProxyChallenge, OK),
12642 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112643 {__LINE__,
12644 nullptr,
asankae2257db2016-10-11 22:03:1612645 AUTH_NONE,
12646 OK,
12647 kServer,
12648 AUTH_SYNC,
12649 ERR_FAILED,
asankac93076192016-10-03 15:46:0212650 2,
12651 kNoSSL,
12652 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612653 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112654 {__LINE__,
12655 nullptr,
asankae2257db2016-10-11 22:03:1612656 AUTH_NONE,
12657 OK,
12658 kServer,
12659 AUTH_ASYNC,
12660 ERR_FAILED,
12661 2,
12662 kNoSSL,
12663 {TestRound(kGet, kServerChallenge, OK),
12664 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112665 {__LINE__,
12666 nullptr,
asankac93076192016-10-03 15:46:0212667 AUTH_NONE,
12668 OK,
12669 kServer,
12670 AUTH_ASYNC,
12671 OK,
12672 2,
12673 kNoSSL,
12674 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512675 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112676 {__LINE__,
12677 nullptr,
asankac93076192016-10-03 15:46:0212678 AUTH_NONE,
12679 OK,
12680 kServer,
12681 AUTH_ASYNC,
12682 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612683 3,
asankac93076192016-10-03 15:46:0212684 kNoSSL,
12685 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612686 // The second round uses a HttpAuthHandlerMock that always succeeds.
12687 TestRound(kGet, kServerChallenge, OK),
12688 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212689 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112690 {__LINE__,
12691 kProxy,
asankac93076192016-10-03 15:46:0212692 AUTH_NONE,
12693 OK,
12694 kServer,
12695 AUTH_NONE,
12696 OK,
12697 1,
12698 kNoSSL,
12699 {TestRound(kGetProxy, kSuccess, OK)}},
12700 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112701 {__LINE__,
12702 kProxy,
asankac93076192016-10-03 15:46:0212703 AUTH_NONE,
12704 OK,
12705 kServer,
12706 AUTH_SYNC,
12707 OK,
12708 2,
12709 kNoSSL,
12710 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512711 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112712 {__LINE__,
12713 kProxy,
asankac93076192016-10-03 15:46:0212714 AUTH_NONE,
12715 OK,
12716 kServer,
12717 AUTH_SYNC,
12718 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612719 3,
asankac93076192016-10-03 15:46:0212720 kNoSSL,
12721 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612722 TestRound(kGetProxy, kServerChallenge, OK),
12723 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112724 {__LINE__,
12725 kProxy,
asankac93076192016-10-03 15:46:0212726 AUTH_NONE,
12727 OK,
12728 kServer,
12729 AUTH_ASYNC,
12730 OK,
12731 2,
12732 kNoSSL,
12733 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512734 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112735 {__LINE__,
12736 kProxy,
asankac93076192016-10-03 15:46:0212737 AUTH_NONE,
12738 OK,
12739 kServer,
12740 AUTH_ASYNC,
12741 ERR_INVALID_AUTH_CREDENTIALS,
12742 2,
12743 kNoSSL,
12744 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612745 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212746 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112747 {__LINE__,
12748 kProxy,
asankac93076192016-10-03 15:46:0212749 AUTH_SYNC,
12750 OK,
12751 kServer,
12752 AUTH_NONE,
12753 OK,
12754 2,
12755 kNoSSL,
12756 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512757 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112758 {__LINE__,
12759 kProxy,
asankac93076192016-10-03 15:46:0212760 AUTH_SYNC,
12761 ERR_INVALID_AUTH_CREDENTIALS,
12762 kServer,
12763 AUTH_NONE,
12764 OK,
12765 2,
12766 kNoSSL,
12767 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612768 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112769 {__LINE__,
12770 kProxy,
asankac93076192016-10-03 15:46:0212771 AUTH_ASYNC,
12772 OK,
12773 kServer,
12774 AUTH_NONE,
12775 OK,
12776 2,
12777 kNoSSL,
12778 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512779 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112780 {__LINE__,
12781 kProxy,
asankac93076192016-10-03 15:46:0212782 AUTH_ASYNC,
12783 ERR_INVALID_AUTH_CREDENTIALS,
12784 kServer,
12785 AUTH_NONE,
12786 OK,
12787 2,
12788 kNoSSL,
12789 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612790 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112791 {__LINE__,
12792 kProxy,
12793 AUTH_ASYNC,
12794 ERR_INVALID_AUTH_CREDENTIALS,
12795 kServer,
12796 AUTH_NONE,
12797 OK,
12798 3,
12799 kNoSSL,
12800 {TestRound(kGetProxy, kProxyChallenge, OK),
12801 TestRound(kGetProxy, kProxyChallenge, OK),
12802 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212803 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112804 {__LINE__,
12805 kProxy,
asankac93076192016-10-03 15:46:0212806 AUTH_SYNC,
12807 OK,
12808 kServer,
12809 AUTH_SYNC,
12810 OK,
12811 3,
12812 kNoSSL,
12813 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512814 TestRound(kGetProxyAuth, kServerChallenge, OK),
12815 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112816 {__LINE__,
12817 kProxy,
asankac93076192016-10-03 15:46:0212818 AUTH_SYNC,
12819 OK,
12820 kServer,
12821 AUTH_SYNC,
12822 ERR_INVALID_AUTH_CREDENTIALS,
12823 3,
12824 kNoSSL,
12825 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512826 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612827 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112828 {__LINE__,
12829 kProxy,
asankac93076192016-10-03 15:46:0212830 AUTH_ASYNC,
12831 OK,
12832 kServer,
12833 AUTH_SYNC,
12834 OK,
12835 3,
12836 kNoSSL,
12837 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512838 TestRound(kGetProxyAuth, kServerChallenge, OK),
12839 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112840 {__LINE__,
12841 kProxy,
asankac93076192016-10-03 15:46:0212842 AUTH_ASYNC,
12843 OK,
12844 kServer,
12845 AUTH_SYNC,
12846 ERR_INVALID_AUTH_CREDENTIALS,
12847 3,
12848 kNoSSL,
12849 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512850 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612851 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112852 {__LINE__,
12853 kProxy,
asankac93076192016-10-03 15:46:0212854 AUTH_SYNC,
12855 OK,
12856 kServer,
12857 AUTH_ASYNC,
12858 OK,
12859 3,
12860 kNoSSL,
12861 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512862 TestRound(kGetProxyAuth, kServerChallenge, OK),
12863 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112864 {__LINE__,
12865 kProxy,
12866 AUTH_SYNC,
12867 ERR_INVALID_AUTH_CREDENTIALS,
12868 kServer,
12869 AUTH_ASYNC,
12870 OK,
12871 4,
12872 kNoSSL,
12873 {TestRound(kGetProxy, kProxyChallenge, OK),
12874 TestRound(kGetProxy, kProxyChallenge, OK),
12875 TestRound(kGetProxyAuth, kServerChallenge, OK),
12876 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12877 {__LINE__,
12878 kProxy,
asankac93076192016-10-03 15:46:0212879 AUTH_SYNC,
12880 OK,
12881 kServer,
12882 AUTH_ASYNC,
12883 ERR_INVALID_AUTH_CREDENTIALS,
12884 3,
12885 kNoSSL,
12886 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512887 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612888 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112889 {__LINE__,
12890 kProxy,
asankac93076192016-10-03 15:46:0212891 AUTH_ASYNC,
12892 OK,
12893 kServer,
12894 AUTH_ASYNC,
12895 OK,
12896 3,
12897 kNoSSL,
12898 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512899 TestRound(kGetProxyAuth, kServerChallenge, OK),
12900 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112901 {__LINE__,
12902 kProxy,
asankac93076192016-10-03 15:46:0212903 AUTH_ASYNC,
12904 OK,
12905 kServer,
12906 AUTH_ASYNC,
12907 ERR_INVALID_AUTH_CREDENTIALS,
12908 3,
12909 kNoSSL,
12910 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512911 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612912 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112913 {__LINE__,
12914 kProxy,
12915 AUTH_ASYNC,
12916 ERR_INVALID_AUTH_CREDENTIALS,
12917 kServer,
12918 AUTH_ASYNC,
12919 ERR_INVALID_AUTH_CREDENTIALS,
12920 4,
12921 kNoSSL,
12922 {TestRound(kGetProxy, kProxyChallenge, OK),
12923 TestRound(kGetProxy, kProxyChallenge, OK),
12924 TestRound(kGetProxyAuth, kServerChallenge, OK),
12925 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212926 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112927 {__LINE__,
12928 nullptr,
asankac93076192016-10-03 15:46:0212929 AUTH_NONE,
12930 OK,
12931 kSecureServer,
12932 AUTH_NONE,
12933 OK,
12934 1,
12935 0,
12936 {TestRound(kGet, kSuccess, OK)}},
12937 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112938 {__LINE__,
12939 nullptr,
asankac93076192016-10-03 15:46:0212940 AUTH_NONE,
12941 OK,
12942 kSecureServer,
12943 AUTH_SYNC,
12944 OK,
12945 2,
12946 0,
12947 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512948 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112949 {__LINE__,
12950 nullptr,
asankac93076192016-10-03 15:46:0212951 AUTH_NONE,
12952 OK,
12953 kSecureServer,
12954 AUTH_SYNC,
12955 ERR_INVALID_AUTH_CREDENTIALS,
12956 2,
12957 0,
asankae2257db2016-10-11 22:03:1612958 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112959 {__LINE__,
12960 nullptr,
asankac93076192016-10-03 15:46:0212961 AUTH_NONE,
12962 OK,
12963 kSecureServer,
12964 AUTH_ASYNC,
12965 OK,
12966 2,
12967 0,
12968 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512969 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112970 {__LINE__,
12971 nullptr,
asankac93076192016-10-03 15:46:0212972 AUTH_NONE,
12973 OK,
12974 kSecureServer,
12975 AUTH_ASYNC,
12976 ERR_INVALID_AUTH_CREDENTIALS,
12977 2,
12978 0,
asankae2257db2016-10-11 22:03:1612979 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212980 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112981 {__LINE__,
12982 kProxy,
asankac93076192016-10-03 15:46:0212983 AUTH_NONE,
12984 OK,
12985 kSecureServer,
12986 AUTH_NONE,
12987 OK,
12988 1,
12989 0,
12990 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12991 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112992 {__LINE__,
12993 kProxy,
asankac93076192016-10-03 15:46:0212994 AUTH_NONE,
12995 OK,
12996 kSecureServer,
12997 AUTH_SYNC,
12998 OK,
12999 2,
13000 0,
13001 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513002 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113003 {__LINE__,
13004 kProxy,
asankac93076192016-10-03 15:46:0213005 AUTH_NONE,
13006 OK,
13007 kSecureServer,
13008 AUTH_SYNC,
13009 ERR_INVALID_AUTH_CREDENTIALS,
13010 2,
13011 0,
13012 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613013 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113014 {__LINE__,
13015 kProxy,
asankac93076192016-10-03 15:46:0213016 AUTH_NONE,
13017 OK,
13018 kSecureServer,
13019 AUTH_ASYNC,
13020 OK,
13021 2,
13022 0,
13023 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513024 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113025 {__LINE__,
13026 kProxy,
asankac93076192016-10-03 15:46:0213027 AUTH_NONE,
13028 OK,
13029 kSecureServer,
13030 AUTH_ASYNC,
13031 ERR_INVALID_AUTH_CREDENTIALS,
13032 2,
13033 0,
13034 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613035 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213036 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113037 {__LINE__,
13038 kProxy,
asankac93076192016-10-03 15:46:0213039 AUTH_SYNC,
13040 OK,
13041 kSecureServer,
13042 AUTH_NONE,
13043 OK,
13044 2,
13045 1,
13046 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513047 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113048 {__LINE__,
13049 kProxy,
asankac93076192016-10-03 15:46:0213050 AUTH_SYNC,
13051 ERR_INVALID_AUTH_CREDENTIALS,
13052 kSecureServer,
13053 AUTH_NONE,
13054 OK,
13055 2,
13056 kNoSSL,
13057 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613058 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113059 {__LINE__,
13060 kProxy,
asankae2257db2016-10-11 22:03:1613061 AUTH_SYNC,
13062 ERR_UNSUPPORTED_AUTH_SCHEME,
13063 kSecureServer,
13064 AUTH_NONE,
13065 OK,
13066 2,
13067 kNoSSL,
13068 {TestRound(kConnect, kProxyChallenge, OK),
13069 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113070 {__LINE__,
13071 kProxy,
asankae2257db2016-10-11 22:03:1613072 AUTH_SYNC,
13073 ERR_UNEXPECTED,
13074 kSecureServer,
13075 AUTH_NONE,
13076 OK,
13077 2,
13078 kNoSSL,
13079 {TestRound(kConnect, kProxyChallenge, OK),
13080 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113081 {__LINE__,
13082 kProxy,
asankac93076192016-10-03 15:46:0213083 AUTH_ASYNC,
13084 OK,
13085 kSecureServer,
13086 AUTH_NONE,
13087 OK,
13088 2,
13089 1,
13090 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513091 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113092 {__LINE__,
13093 kProxy,
asankac93076192016-10-03 15:46:0213094 AUTH_ASYNC,
13095 ERR_INVALID_AUTH_CREDENTIALS,
13096 kSecureServer,
13097 AUTH_NONE,
13098 OK,
13099 2,
13100 kNoSSL,
13101 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613102 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213103 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113104 {__LINE__,
13105 kProxy,
asankac93076192016-10-03 15:46:0213106 AUTH_SYNC,
13107 OK,
13108 kSecureServer,
13109 AUTH_SYNC,
13110 OK,
13111 3,
13112 1,
13113 {TestRound(kConnect, kProxyChallenge, OK),
13114 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13115 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513116 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113117 {__LINE__,
13118 kProxy,
asankac93076192016-10-03 15:46:0213119 AUTH_SYNC,
13120 OK,
13121 kSecureServer,
13122 AUTH_SYNC,
13123 ERR_INVALID_AUTH_CREDENTIALS,
13124 3,
13125 1,
13126 {TestRound(kConnect, kProxyChallenge, OK),
13127 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13128 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613129 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113130 {__LINE__,
13131 kProxy,
asankac93076192016-10-03 15:46:0213132 AUTH_ASYNC,
13133 OK,
13134 kSecureServer,
13135 AUTH_SYNC,
13136 OK,
13137 3,
13138 1,
13139 {TestRound(kConnect, kProxyChallenge, OK),
13140 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13141 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513142 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113143 {__LINE__,
13144 kProxy,
asankac93076192016-10-03 15:46:0213145 AUTH_ASYNC,
13146 OK,
13147 kSecureServer,
13148 AUTH_SYNC,
13149 ERR_INVALID_AUTH_CREDENTIALS,
13150 3,
13151 1,
13152 {TestRound(kConnect, kProxyChallenge, OK),
13153 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13154 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613155 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113156 {__LINE__,
13157 kProxy,
asankac93076192016-10-03 15:46:0213158 AUTH_SYNC,
13159 OK,
13160 kSecureServer,
13161 AUTH_ASYNC,
13162 OK,
13163 3,
13164 1,
13165 {TestRound(kConnect, kProxyChallenge, OK),
13166 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13167 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513168 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113169 {__LINE__,
13170 kProxy,
asankac93076192016-10-03 15:46:0213171 AUTH_SYNC,
13172 OK,
13173 kSecureServer,
13174 AUTH_ASYNC,
13175 ERR_INVALID_AUTH_CREDENTIALS,
13176 3,
13177 1,
13178 {TestRound(kConnect, kProxyChallenge, OK),
13179 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13180 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613181 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113182 {__LINE__,
13183 kProxy,
asankac93076192016-10-03 15:46:0213184 AUTH_ASYNC,
13185 OK,
13186 kSecureServer,
13187 AUTH_ASYNC,
13188 OK,
13189 3,
13190 1,
13191 {TestRound(kConnect, kProxyChallenge, OK),
13192 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13193 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513194 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113195 {__LINE__,
13196 kProxy,
asankac93076192016-10-03 15:46:0213197 AUTH_ASYNC,
13198 OK,
13199 kSecureServer,
13200 AUTH_ASYNC,
13201 ERR_INVALID_AUTH_CREDENTIALS,
13202 3,
13203 1,
13204 {TestRound(kConnect, kProxyChallenge, OK),
13205 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13206 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613207 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113208 {__LINE__,
13209 kProxy,
13210 AUTH_ASYNC,
13211 ERR_INVALID_AUTH_CREDENTIALS,
13212 kSecureServer,
13213 AUTH_ASYNC,
13214 ERR_INVALID_AUTH_CREDENTIALS,
13215 4,
13216 2,
13217 {TestRound(kConnect, kProxyChallenge, OK),
13218 TestRound(kConnect, kProxyChallenge, OK),
13219 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13220 &kServerChallenge),
13221 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513222 };
13223
asanka463ca4262016-11-16 02:34:3113224 for (const auto& test_config : test_configs) {
13225 SCOPED_TRACE(::testing::Message() << "Test config at "
13226 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813227 HttpAuthHandlerMock::Factory* auth_factory(
13228 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713229 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913230 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613231
13232 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513233 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113234 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813235 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13236 std::string auth_challenge = "Mock realm=proxy";
13237 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413238 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13239 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813240 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013241 empty_ssl_info, origin,
13242 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813243 auth_handler->SetGenerateExpectation(
13244 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113245 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813246 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13247 }
[email protected]044de0642010-06-17 10:42:1513248 }
13249 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013250 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513251 std::string auth_challenge = "Mock realm=server";
13252 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413253 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13254 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513255 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013256 empty_ssl_info, origin,
13257 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513258 auth_handler->SetGenerateExpectation(
13259 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113260 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813261 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613262
13263 // The second handler always succeeds. It should only be used where there
13264 // are multiple auth sessions for server auth in the same network
13265 // transaction using the same auth scheme.
13266 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913267 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613268 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13269 empty_ssl_info, origin,
13270 NetLogWithSource());
13271 second_handler->SetGenerateExpectation(true, OK);
13272 auth_factory->AddMockHandler(second_handler.release(),
13273 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513274 }
13275 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913276 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913277 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13278 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513279 } else {
Bence Béky53a5aef2018-03-29 21:54:1213280 session_deps_.proxy_resolution_service =
13281 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513282 }
13283
13284 HttpRequestInfo request;
13285 request.method = "GET";
13286 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1013287 request.traffic_annotation =
13288 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513289
danakj1fd259a02016-04-16 03:17:0913290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513291
rchcb68dc62015-05-21 04:45:3613292 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13293
13294 std::vector<std::vector<MockRead>> mock_reads(1);
13295 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513296 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213297 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513298 const TestRound& read_write_round = test_config.rounds[round];
13299
13300 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613301 mock_reads.back().push_back(read_write_round.read);
13302 mock_writes.back().push_back(read_write_round.write);
13303
13304 // kProxyChallenge uses Proxy-Connection: close which means that the
13305 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413306 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613307 mock_reads.push_back(std::vector<MockRead>());
13308 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513309 }
13310
rchcb68dc62015-05-21 04:45:3613311 if (read_write_round.extra_read) {
13312 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513313 }
rchcb68dc62015-05-21 04:45:3613314 if (read_write_round.extra_write) {
13315 mock_writes.back().push_back(*read_write_round.extra_write);
13316 }
[email protected]044de0642010-06-17 10:42:1513317
13318 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513319 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713320 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513321 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613322 }
[email protected]044de0642010-06-17 10:42:1513323
danakj1fd259a02016-04-16 03:17:0913324 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613325 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913326 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0113327 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3613328 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213329 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613330 }
13331
mmenkecc2298e2015-12-07 18:20:1813332 // Transaction must be created after DataProviders, so it's destroyed before
13333 // they are as well.
13334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13335
rchcb68dc62015-05-21 04:45:3613336 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213337 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613338 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513339 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113340 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513341 int rv;
13342 if (round == 0) {
tfarina42834112016-09-22 13:38:2013343 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513344 } else {
[email protected]49639fa2011-12-20 23:22:4113345 rv = trans.RestartWithAuth(
13346 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513347 }
13348 if (rv == ERR_IO_PENDING)
13349 rv = callback.WaitForResult();
13350
13351 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613352 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013353 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513354 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513355 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13356 continue;
13357 }
13358 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213359 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513360 } else {
wezca1070932016-05-26 20:30:5213361 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613362 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513363 }
13364 }
[email protected]e5ae96a2010-04-14 20:12:4513365 }
13366}
13367
bncd16676a2016-07-20 16:23:0113368TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413369 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413370 HttpAuthHandlerMock::Factory* auth_factory(
13371 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713372 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1213373 session_deps_.proxy_resolution_service =
13374 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713375 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13376 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413377
13378 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13379 auth_handler->set_connection_based(true);
13380 std::string auth_challenge = "Mock realm=server";
13381 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413382 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13383 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913384 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413385 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013386 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813387 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413388
[email protected]c871bce92010-07-15 21:51:1413389 int rv = OK;
13390 const HttpResponseInfo* response = NULL;
13391 HttpRequestInfo request;
13392 request.method = "GET";
13393 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1013394 request.traffic_annotation =
13395 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713396
danakj1fd259a02016-04-16 03:17:0913397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013398
13399 // Use a TCP Socket Pool with only one connection per group. This is used
13400 // to validate that the TCP socket is not released to the pool between
13401 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213402 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813403 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013404 50, // Max sockets for pool
13405 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113406 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13407 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913408 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213409 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813410 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013411
bnc691fda62016-08-12 00:43:1613412 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113413 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413414
13415 const MockWrite kGet(
13416 "GET / HTTP/1.1\r\n"
13417 "Host: www.example.com\r\n"
13418 "Connection: keep-alive\r\n\r\n");
13419 const MockWrite kGetAuth(
13420 "GET / HTTP/1.1\r\n"
13421 "Host: www.example.com\r\n"
13422 "Connection: keep-alive\r\n"
13423 "Authorization: auth_token\r\n\r\n");
13424
13425 const MockRead kServerChallenge(
13426 "HTTP/1.1 401 Unauthorized\r\n"
13427 "WWW-Authenticate: Mock realm=server\r\n"
13428 "Content-Type: text/html; charset=iso-8859-1\r\n"
13429 "Content-Length: 14\r\n\r\n"
13430 "Unauthorized\r\n");
13431 const MockRead kSuccess(
13432 "HTTP/1.1 200 OK\r\n"
13433 "Content-Type: text/html; charset=iso-8859-1\r\n"
13434 "Content-Length: 3\r\n\r\n"
13435 "Yes");
13436
13437 MockWrite writes[] = {
13438 // First round
13439 kGet,
13440 // Second round
13441 kGetAuth,
13442 // Third round
13443 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013444 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013445 kGetAuth,
13446 // Competing request
13447 kGet,
[email protected]c871bce92010-07-15 21:51:1413448 };
13449 MockRead reads[] = {
13450 // First round
13451 kServerChallenge,
13452 // Second round
13453 kServerChallenge,
13454 // Third round
[email protected]eca50e122010-09-11 14:03:3013455 kServerChallenge,
13456 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413457 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013458 // Competing response
13459 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413460 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113461 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0713462 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413463
thestig9d3bb0c2015-01-24 00:49:5113464 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013465
13466 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413467 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013468 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413469 if (rv == ERR_IO_PENDING)
13470 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113471 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613472 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213473 ASSERT_TRUE(response);
13474 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813475 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113476 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13477 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413478
[email protected]7ef4cbbb2011-02-06 11:19:1013479 // In between rounds, another request comes in for the same domain.
13480 // It should not be able to grab the TCP socket that trans has already
13481 // claimed.
bnc691fda62016-08-12 00:43:1613482 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113483 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013484 rv = trans_compete.Start(&request, callback_compete.callback(),
13485 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013487 // callback_compete.WaitForResult at this point would stall forever,
13488 // since the HttpNetworkTransaction does not release the request back to
13489 // the pool until after authentication completes.
13490
13491 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413492 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613493 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413494 if (rv == ERR_IO_PENDING)
13495 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113496 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613497 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213498 ASSERT_TRUE(response);
13499 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813500 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113501 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13502 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413503
[email protected]7ef4cbbb2011-02-06 11:19:1013504 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413505 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613506 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413507 if (rv == ERR_IO_PENDING)
13508 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113509 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613510 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213511 ASSERT_TRUE(response);
13512 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813513 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113514 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13515 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013516
[email protected]7ef4cbbb2011-02-06 11:19:1013517 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013518 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613519 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013520 if (rv == ERR_IO_PENDING)
13521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113522 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613523 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213524 ASSERT_TRUE(response);
13525 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813526 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013527
asanka463ca4262016-11-16 02:34:3113528 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13529 // auth handler should transition to a DONE state in concert with the remote
13530 // server. But that's not something we can test here with a mock handler.
13531 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13532 auth_handler->state());
13533
[email protected]7ef4cbbb2011-02-06 11:19:1013534 // Read the body since the fourth round was successful. This will also
13535 // release the socket back to the pool.
13536 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613537 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013538 if (rv == ERR_IO_PENDING)
13539 rv = callback.WaitForResult();
13540 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613541 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013542 EXPECT_EQ(0, rv);
13543 // There are still 0 idle sockets, since the trans_compete transaction
13544 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813545 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013546
13547 // The competing request can now finish. Wait for the headers and then
13548 // read the body.
13549 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113550 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613551 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013552 if (rv == ERR_IO_PENDING)
13553 rv = callback.WaitForResult();
13554 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613555 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013556 EXPECT_EQ(0, rv);
13557
13558 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813559 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413560}
13561
[email protected]65041fa2010-05-21 06:56:5313562// This tests the case that a request is issued via http instead of spdy after
13563// npn is negotiated.
bncd16676a2016-07-20 16:23:0113564TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313565 HttpRequestInfo request;
13566 request.method = "GET";
bncce36dca22015-04-21 22:11:2313567 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013568 request.traffic_annotation =
13569 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313570
13571 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313572 MockWrite(
13573 "GET / HTTP/1.1\r\n"
13574 "Host: www.example.org\r\n"
13575 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313576 };
13577
13578 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213579 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313580 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213581 MockRead("\r\n"),
13582 MockRead("hello world"),
13583 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313584 };
13585
[email protected]8ddf8322012-02-23 18:08:0613586 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613587 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313588
[email protected]bb88e1d32013-05-03 23:11:0713589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313590
Ryan Sleevib8d7ea02018-05-07 20:01:0113591 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0713592 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313593
[email protected]49639fa2011-12-20 23:22:4113594 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313595
danakj1fd259a02016-04-16 03:17:0913596 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313598
tfarina42834112016-09-22 13:38:2013599 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313600
robpercival214763f2016-07-01 23:27:0113601 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13602 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313603
bnc691fda62016-08-12 00:43:1613604 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213605 ASSERT_TRUE(response);
13606 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313607 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13608
13609 std::string response_data;
bnc691fda62016-08-12 00:43:1613610 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313611 EXPECT_EQ("hello world", response_data);
13612
13613 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213614 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313615}
[email protected]26ef6582010-06-24 02:30:4713616
bnc55ff9da2015-08-19 18:42:3513617// Simulate the SSL handshake completing with an NPN negotiation followed by an
13618// immediate server closing of the socket.
13619// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113620TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713621 HttpRequestInfo request;
13622 request.method = "GET";
bncce36dca22015-04-21 22:11:2313623 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013624 request.traffic_annotation =
13625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713626
[email protected]8ddf8322012-02-23 18:08:0613627 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613628 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713630
Bence Béky27ad0a12018-02-08 00:35:4813631 SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113632 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713633
13634 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613635 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713636 };
13637
Ryan Sleevib8d7ea02018-05-07 20:01:0113638 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713639 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713640
[email protected]49639fa2011-12-20 23:22:4113641 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713642
danakj1fd259a02016-04-16 03:17:0913643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713645
tfarina42834112016-09-22 13:38:2013646 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13648 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713649}
[email protected]65d34382010-07-01 18:12:2613650
[email protected]795cbf82013-07-22 09:37:2713651// A subclass of HttpAuthHandlerMock that records the request URL when
13652// it gets it. This is needed since the auth handler may get destroyed
13653// before we get a chance to query it.
13654class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13655 public:
13656 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13657
Chris Watkins7a41d3552017-12-01 02:13:2713658 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713659
13660 protected:
dchengb03027d2014-10-21 12:00:2013661 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13662 const HttpRequestInfo* request,
13663 const CompletionCallback& callback,
13664 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713665 *url_ = request->url;
13666 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13667 credentials, request, callback, auth_token);
13668 }
13669
13670 private:
13671 GURL* url_;
13672};
13673
[email protected]8e6441ca2010-08-19 05:56:3813674// Test that if we cancel the transaction as the connection is completing, that
13675// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113676TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813677 // Setup everything about the connection to complete synchronously, so that
13678 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13679 // for is the callback from the HttpStreamRequest.
13680 // Then cancel the transaction.
13681 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613682 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813683 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613684 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13685 MockRead(SYNCHRONOUS, "hello world"),
13686 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813687 };
13688
[email protected]8e6441ca2010-08-19 05:56:3813689 HttpRequestInfo request;
13690 request.method = "GET";
bncce36dca22015-04-21 22:11:2313691 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013692 request.traffic_annotation =
13693 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813694
[email protected]bb88e1d32013-05-03 23:11:0713695 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813697 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913698 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713699
Ryan Sleevib8d7ea02018-05-07 20:01:0113700 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3813701 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713702 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813703
[email protected]49639fa2011-12-20 23:22:4113704 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813705
vishal.b62985ca92015-04-17 08:45:5113706 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113707 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813709 trans.reset(); // Cancel the transaction here.
13710
fdoray92e35a72016-06-10 15:54:5513711 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013712}
13713
[email protected]ecab6e052014-05-16 14:58:1213714// Test that if a transaction is cancelled after receiving the headers, the
13715// stream is drained properly and added back to the socket pool. The main
13716// purpose of this test is to make sure that an HttpStreamParser can be read
13717// from after the HttpNetworkTransaction and the objects it owns have been
13718// deleted.
13719// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113720TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213721 MockRead data_reads[] = {
13722 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13723 MockRead(ASYNC, "Content-Length: 2\r\n"),
13724 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13725 MockRead(ASYNC, "1"),
13726 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13727 // HttpNetworkTransaction has been deleted.
13728 MockRead(ASYNC, "2"),
13729 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13730 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113731 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1213732 session_deps_.socket_factory->AddSocketDataProvider(&data);
13733
danakj1fd259a02016-04-16 03:17:0913734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213735
13736 {
13737 HttpRequestInfo request;
13738 request.method = "GET";
bncce36dca22015-04-21 22:11:2313739 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013740 request.traffic_annotation =
13741 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213742
dcheng48459ac22014-08-26 00:46:4113743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213744 TestCompletionCallback callback;
13745
tfarina42834112016-09-22 13:38:2013746 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213748 callback.WaitForResult();
13749
13750 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213751 ASSERT_TRUE(response);
13752 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213753 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13754
13755 // The transaction and HttpRequestInfo are deleted.
13756 }
13757
13758 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513759 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213760
13761 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113762 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213763}
13764
[email protected]76a505b2010-08-25 06:23:0013765// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113766TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913767 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913768 ProxyResolutionService::CreateFixedFromPacResult(
13769 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113770 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713771 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013773
[email protected]76a505b2010-08-25 06:23:0013774 HttpRequestInfo request;
13775 request.method = "GET";
bncce36dca22015-04-21 22:11:2313776 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013777 request.traffic_annotation =
13778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013779
13780 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313781 MockWrite(
13782 "GET http://www.example.org/ HTTP/1.1\r\n"
13783 "Host: www.example.org\r\n"
13784 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013785 };
13786
13787 MockRead data_reads1[] = {
13788 MockRead("HTTP/1.1 200 OK\r\n"),
13789 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13790 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613791 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013792 };
13793
Ryan Sleevib8d7ea02018-05-07 20:01:0113794 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013796
[email protected]49639fa2011-12-20 23:22:4113797 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013798
bnc691fda62016-08-12 00:43:1613799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913800 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613801 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913802 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13803 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013804
bnc691fda62016-08-12 00:43:1613805 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013807
13808 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113809 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013810
bnc691fda62016-08-12 00:43:1613811 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213812 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013813
13814 EXPECT_TRUE(response->headers->IsKeepAlive());
13815 EXPECT_EQ(200, response->headers->response_code());
13816 EXPECT_EQ(100, response->headers->GetContentLength());
13817 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713818 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13819 HostPortPair::FromString("myproxy:70")),
13820 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913821 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13822 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13823 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013824 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013825
13826 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613827 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013828 TestLoadTimingNotReusedWithPac(load_timing_info,
13829 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013830}
13831
13832// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113833TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913834 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913835 ProxyResolutionService::CreateFixedFromPacResult(
13836 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113837 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713838 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013840
[email protected]76a505b2010-08-25 06:23:0013841 HttpRequestInfo request;
13842 request.method = "GET";
bncce36dca22015-04-21 22:11:2313843 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013844 request.traffic_annotation =
13845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013846
13847 // Since we have proxy, should try to establish tunnel.
13848 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713849 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13850 "Host: www.example.org:443\r\n"
13851 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013852
rsleevidb16bb02015-11-12 23:47:1713853 MockWrite("GET / HTTP/1.1\r\n"
13854 "Host: www.example.org\r\n"
13855 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013856 };
13857
13858 MockRead data_reads1[] = {
13859 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13860
13861 MockRead("HTTP/1.1 200 OK\r\n"),
13862 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13863 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613864 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013865 };
13866
Ryan Sleevib8d7ea02018-05-07 20:01:0113867 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713868 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613869 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013871
[email protected]49639fa2011-12-20 23:22:4113872 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013873
bnc691fda62016-08-12 00:43:1613874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913875 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613876 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913877 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13878 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013879
bnc691fda62016-08-12 00:43:1613880 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013882
13883 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113884 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613885 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013886 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013887 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013888 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13889 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013890 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013891 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013892 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13893 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013894
bnc691fda62016-08-12 00:43:1613895 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213896 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013897
13898 EXPECT_TRUE(response->headers->IsKeepAlive());
13899 EXPECT_EQ(200, response->headers->response_code());
13900 EXPECT_EQ(100, response->headers->GetContentLength());
13901 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13902 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713903 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13904 HostPortPair::FromString("myproxy:70")),
13905 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913906 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13907 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13908 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013909
13910 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613911 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013912 TestLoadTimingNotReusedWithPac(load_timing_info,
13913 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013914}
13915
rsleevidb16bb02015-11-12 23:47:1713916// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13917// literal host.
bncd16676a2016-07-20 16:23:0113918TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913919 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913920 ProxyResolutionService::CreateFixedFromPacResult(
13921 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713922 BoundTestNetLog log;
13923 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913924 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713925
13926 HttpRequestInfo request;
13927 request.method = "GET";
13928 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1013929 request.traffic_annotation =
13930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713931
13932 // Since we have proxy, should try to establish tunnel.
13933 MockWrite data_writes1[] = {
13934 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13935 "Host: [::1]:443\r\n"
13936 "Proxy-Connection: keep-alive\r\n\r\n"),
13937
13938 MockWrite("GET / HTTP/1.1\r\n"
13939 "Host: [::1]\r\n"
13940 "Connection: keep-alive\r\n\r\n"),
13941 };
13942
13943 MockRead data_reads1[] = {
13944 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13945
13946 MockRead("HTTP/1.1 200 OK\r\n"),
13947 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13948 MockRead("Content-Length: 100\r\n\r\n"),
13949 MockRead(SYNCHRONOUS, OK),
13950 };
13951
Ryan Sleevib8d7ea02018-05-07 20:01:0113952 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1713953 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13954 SSLSocketDataProvider ssl(ASYNC, OK);
13955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13956
13957 TestCompletionCallback callback1;
13958
bnc691fda62016-08-12 00:43:1613959 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713960
bnc691fda62016-08-12 00:43:1613961 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713963
13964 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113965 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713966 TestNetLogEntry::List entries;
13967 log.GetEntries(&entries);
13968 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013969 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13970 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713971 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013972 entries, pos,
13973 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13974 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713975
bnc691fda62016-08-12 00:43:1613976 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213977 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713978
13979 EXPECT_TRUE(response->headers->IsKeepAlive());
13980 EXPECT_EQ(200, response->headers->response_code());
13981 EXPECT_EQ(100, response->headers->GetContentLength());
13982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13983 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713984 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13985 HostPortPair::FromString("myproxy:70")),
13986 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713987
13988 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613989 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713990 TestLoadTimingNotReusedWithPac(load_timing_info,
13991 CONNECT_TIMING_HAS_SSL_TIMES);
13992}
13993
[email protected]76a505b2010-08-25 06:23:0013994// Test a basic HTTPS GET request through a proxy, but the server hangs up
13995// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113996TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4913997 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
13998 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113999 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714000 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014002
[email protected]76a505b2010-08-25 06:23:0014003 HttpRequestInfo request;
14004 request.method = "GET";
bncce36dca22015-04-21 22:11:2314005 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014006 request.traffic_annotation =
14007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014008
14009 // Since we have proxy, should try to establish tunnel.
14010 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714011 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14012 "Host: www.example.org:443\r\n"
14013 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014014
rsleevidb16bb02015-11-12 23:47:1714015 MockWrite("GET / HTTP/1.1\r\n"
14016 "Host: www.example.org\r\n"
14017 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014018 };
14019
14020 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014021 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614022 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014023 };
14024
Ryan Sleevib8d7ea02018-05-07 20:01:0114025 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714026 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614027 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714028 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014029
[email protected]49639fa2011-12-20 23:22:4114030 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014031
bnc691fda62016-08-12 00:43:1614032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014033
bnc691fda62016-08-12 00:43:1614034 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014036
14037 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114038 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614039 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014040 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014041 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014042 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14043 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014044 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014045 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014046 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14047 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014048}
14049
[email protected]749eefa82010-09-13 22:14:0314050// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114051TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114052 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914053 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114054 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314055
bnc42331402016-07-25 13:36:1514056 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114057 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314058 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114059 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314060 };
14061
Ryan Sleevib8d7ea02018-05-07 20:01:0114062 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714063 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314064
[email protected]8ddf8322012-02-23 18:08:0614065 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614066 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314068
danakj1fd259a02016-04-16 03:17:0914069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314070
14071 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314072 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014073 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414074 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714075 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214076 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314077
14078 HttpRequestInfo request;
14079 request.method = "GET";
bncce36dca22015-04-21 22:11:2314080 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014081 request.traffic_annotation =
14082 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314083
14084 // This is the important line that marks this as a preconnect.
14085 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14086
bnc691fda62016-08-12 00:43:1614087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314088
[email protected]41d64e82013-07-03 22:44:2614089 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014090 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14092 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314093}
14094
[email protected]73b8dd222010-11-11 19:55:2414095// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614096// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214097void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714098 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914099 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714100 request_info.url = GURL("https://www.example.com/");
14101 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914102 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014103 request_info.traffic_annotation =
14104 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714105
[email protected]8ddf8322012-02-23 18:08:0614106 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914107 MockWrite data_writes[] = {
14108 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414109 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114110 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714111 session_deps_.socket_factory->AddSocketDataProvider(&data);
14112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414113
danakj1fd259a02016-04-16 03:17:0914114 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614115 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414116
[email protected]49639fa2011-12-20 23:22:4114117 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014118 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914119 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414120 rv = callback.WaitForResult();
14121 ASSERT_EQ(error, rv);
14122}
14123
bncd16676a2016-07-20 16:23:0114124TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414125 // Just check a grab bag of cert errors.
14126 static const int kErrors[] = {
14127 ERR_CERT_COMMON_NAME_INVALID,
14128 ERR_CERT_AUTHORITY_INVALID,
14129 ERR_CERT_DATE_INVALID,
14130 };
14131 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614132 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14133 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414134 }
14135}
14136
[email protected]bd0b6772011-01-11 19:59:3014137// Ensure that a client certificate is removed from the SSL client auth
14138// cache when:
14139// 1) No proxy is involved.
14140// 2) TLS False Start is disabled.
14141// 3) The initial TLS handshake requests a client certificate.
14142// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114143TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914144 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714145 request_info.url = GURL("https://www.example.com/");
14146 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914147 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014148 request_info.traffic_annotation =
14149 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714150
[email protected]bd0b6772011-01-11 19:59:3014151 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114152 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014153
14154 // [ssl_]data1 contains the data for the first SSL handshake. When a
14155 // CertificateRequest is received for the first time, the handshake will
14156 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914157 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014158 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714159 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114160 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714161 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014162
14163 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14164 // False Start is not being used, the result of the SSL handshake will be
14165 // returned as part of the SSLClientSocket::Connect() call. This test
14166 // matches the result of a server sending a handshake_failure alert,
14167 // rather than a Finished message, because it requires a client
14168 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914169 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014170 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114172 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714173 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014174
14175 // [ssl_]data3 contains the data for the third SSL handshake. When a
14176 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214177 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14178 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014179 // of the HttpNetworkTransaction. Because this test failure is due to
14180 // requiring a client certificate, this fallback handshake should also
14181 // fail.
ttuttle859dc7a2015-04-23 19:42:2914182 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014183 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114185 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714186 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014187
[email protected]80c75f682012-05-26 16:22:1714188 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14189 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214190 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14191 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714192 // of the HttpNetworkTransaction. Because this test failure is due to
14193 // requiring a client certificate, this fallback handshake should also
14194 // fail.
ttuttle859dc7a2015-04-23 19:42:2914195 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714196 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714197 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114198 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0714199 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714200
danakj1fd259a02016-04-16 03:17:0914201 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014203
[email protected]bd0b6772011-01-11 19:59:3014204 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114205 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014206 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114207 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014208
14209 // Complete the SSL handshake, which should abort due to requiring a
14210 // client certificate.
14211 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114212 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014213
14214 // Indicate that no certificate should be supplied. From the perspective
14215 // of SSLClientCertCache, NULL is just as meaningful as a real
14216 // certificate, so this is the same as supply a
14217 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614218 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114219 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014220
14221 // Ensure the certificate was added to the client auth cache before
14222 // allowing the connection to continue restarting.
14223 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414224 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114225 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414226 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214227 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014228
14229 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714230 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14231 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014232 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114233 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014234
14235 // Ensure that the client certificate is removed from the cache on a
14236 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114237 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414238 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014239}
14240
14241// Ensure that a client certificate is removed from the SSL client auth
14242// cache when:
14243// 1) No proxy is involved.
14244// 2) TLS False Start is enabled.
14245// 3) The initial TLS handshake requests a client certificate.
14246// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114247TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914248 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714249 request_info.url = GURL("https://www.example.com/");
14250 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914251 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014252 request_info.traffic_annotation =
14253 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714254
[email protected]bd0b6772011-01-11 19:59:3014255 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114256 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014257
14258 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14259 // return successfully after reading up to the peer's Certificate message.
14260 // This is to allow the caller to call SSLClientSocket::Write(), which can
14261 // enqueue application data to be sent in the same packet as the
14262 // ChangeCipherSpec and Finished messages.
14263 // The actual handshake will be finished when SSLClientSocket::Read() is
14264 // called, which expects to process the peer's ChangeCipherSpec and
14265 // Finished messages. If there was an error negotiating with the peer,
14266 // such as due to the peer requiring a client certificate when none was
14267 // supplied, the alert sent by the peer won't be processed until Read() is
14268 // called.
14269
14270 // Like the non-False Start case, when a client certificate is requested by
14271 // the peer, the handshake is aborted during the Connect() call.
14272 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914273 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014274 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114276 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714277 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014278
14279 // When a client certificate is supplied, Connect() will not be aborted
14280 // when the peer requests the certificate. Instead, the handshake will
14281 // artificially succeed, allowing the caller to write the HTTP request to
14282 // the socket. The handshake messages are not processed until Read() is
14283 // called, which then detects that the handshake was aborted, due to the
14284 // peer sending a handshake_failure because it requires a client
14285 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914286 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014287 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914289 MockRead data2_reads[] = {
14290 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014291 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114292 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714293 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014294
14295 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714296 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14297 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914298 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014299 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714300 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114301 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714302 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014303
[email protected]80c75f682012-05-26 16:22:1714304 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14305 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914306 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714307 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114309 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714310 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714311
[email protected]7799de12013-05-30 05:52:5114312 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914313 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114314 ssl_data5.cert_request_info = cert_request.get();
14315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0114316 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5114317 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14318
danakj1fd259a02016-04-16 03:17:0914319 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614320 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014321
[email protected]bd0b6772011-01-11 19:59:3014322 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114323 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014324 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114325 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014326
14327 // Complete the SSL handshake, which should abort due to requiring a
14328 // client certificate.
14329 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114330 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014331
14332 // Indicate that no certificate should be supplied. From the perspective
14333 // of SSLClientCertCache, NULL is just as meaningful as a real
14334 // certificate, so this is the same as supply a
14335 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614336 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114337 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014338
14339 // Ensure the certificate was added to the client auth cache before
14340 // allowing the connection to continue restarting.
14341 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414342 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114343 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414344 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214345 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014346
[email protected]bd0b6772011-01-11 19:59:3014347 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714348 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14349 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014350 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114351 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014352
14353 // Ensure that the client certificate is removed from the cache on a
14354 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114355 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414356 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014357}
14358
[email protected]8c405132011-01-11 22:03:1814359// Ensure that a client certificate is removed from the SSL client auth
14360// cache when:
14361// 1) An HTTPS proxy is involved.
14362// 3) The HTTPS proxy requests a client certificate.
14363// 4) The client supplies an invalid/unacceptable certificate for the
14364// proxy.
14365// The test is repeated twice, first for connecting to an HTTPS endpoint,
14366// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114367TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914368 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14369 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114370 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714371 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814372
14373 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114374 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814375
14376 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14377 // [ssl_]data[1-3]. Rather than represending the endpoint
14378 // (www.example.com:443), they represent failures with the HTTPS proxy
14379 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914380 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814381 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114383 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714384 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814385
ttuttle859dc7a2015-04-23 19:42:2914386 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814387 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114389 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714390 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814391
[email protected]80c75f682012-05-26 16:22:1714392 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14393#if 0
ttuttle859dc7a2015-04-23 19:42:2914394 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814395 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114397 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714398 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714399#endif
[email protected]8c405132011-01-11 22:03:1814400
ttuttle859dc7a2015-04-23 19:42:2914401 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814402 requests[0].url = GURL("https://www.example.com/");
14403 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914404 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014405 requests[0].traffic_annotation =
14406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814407
14408 requests[1].url = GURL("http://www.example.com/");
14409 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914410 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014411 requests[1].traffic_annotation =
14412 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814413
14414 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714415 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914416 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814418
14419 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114420 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014421 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114422 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814423
14424 // Complete the SSL handshake, which should abort due to requiring a
14425 // client certificate.
14426 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114427 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814428
14429 // Indicate that no certificate should be supplied. From the perspective
14430 // of SSLClientCertCache, NULL is just as meaningful as a real
14431 // certificate, so this is the same as supply a
14432 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614433 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114434 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814435
14436 // Ensure the certificate was added to the client auth cache before
14437 // allowing the connection to continue restarting.
14438 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414439 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114440 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414441 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214442 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814443 // Ensure the certificate was NOT cached for the endpoint. This only
14444 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114445 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414446 HostPortPair("www.example.com", 443), &client_cert,
14447 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814448
14449 // Restart the handshake. This will consume ssl_data2, which fails, and
14450 // then consume ssl_data3, which should also fail. The result code is
14451 // checked against what ssl_data3 should return.
14452 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114453 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814454
14455 // Now that the new handshake has failed, ensure that the client
14456 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114457 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414458 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114459 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414460 HostPortPair("www.example.com", 443), &client_cert,
14461 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814462 }
14463}
14464
bncd16676a2016-07-20 16:23:0114465TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614466 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914467 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614469
bnc032658ba2016-09-26 18:17:1514470 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614471
bncdf80d44fd2016-07-15 20:27:4114472 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914473 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814474 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114475 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714476 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614477 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114478 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614479 };
bnc42331402016-07-25 13:36:1514480 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114481 SpdySerializedFrame host1_resp_body(
14482 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514483 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114484 SpdySerializedFrame host2_resp_body(
14485 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614486 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114487 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14488 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314489 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614490 };
14491
eroman36d84e54432016-03-17 03:23:0214492 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214493 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114494 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714495 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614496
[email protected]aa22b242011-11-16 18:58:2914497 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614498 HttpRequestInfo request1;
14499 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314500 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614501 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014502 request1.traffic_annotation =
14503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014504 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614505
tfarina42834112016-09-22 13:38:2014506 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14508 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614509
14510 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214511 ASSERT_TRUE(response);
14512 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214513 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614514
14515 std::string response_data;
robpercival214763f2016-07-01 23:27:0114516 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614517 EXPECT_EQ("hello!", response_data);
14518
bnca4d611d2016-09-22 19:55:3714519 // Preload mail.example.com into HostCache.
14520 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014521 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614522 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014523 std::unique_ptr<HostResolver::Request> request;
14524 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14525 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014526 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114527 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714528 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114529 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614530
14531 HttpRequestInfo request2;
14532 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714533 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614534 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014535 request2.traffic_annotation =
14536 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014537 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614538
tfarina42834112016-09-22 13:38:2014539 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14541 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614542
14543 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214544 ASSERT_TRUE(response);
14545 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214546 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614547 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214548 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114549 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614550 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614551}
14552
bncd16676a2016-07-20 16:23:0114553TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214554 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914555 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214557
bnc032658ba2016-09-26 18:17:1514558 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214559
bncdf80d44fd2016-07-15 20:27:4114560 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914561 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814562 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114563 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714564 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214565 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114566 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214567 };
bnc42331402016-07-25 13:36:1514568 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114569 SpdySerializedFrame host1_resp_body(
14570 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514571 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114572 SpdySerializedFrame host2_resp_body(
14573 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214574 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114575 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14576 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314577 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214578 };
14579
eroman36d84e54432016-03-17 03:23:0214580 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214581 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114582 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714583 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214584
14585 TestCompletionCallback callback;
14586 HttpRequestInfo request1;
14587 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314588 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214589 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014590 request1.traffic_annotation =
14591 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014592 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214593
tfarina42834112016-09-22 13:38:2014594 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14596 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214597
14598 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214599 ASSERT_TRUE(response);
14600 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214601 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214602
14603 std::string response_data;
robpercival214763f2016-07-01 23:27:0114604 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214605 EXPECT_EQ("hello!", response_data);
14606
14607 HttpRequestInfo request2;
14608 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714609 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214610 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014611 request2.traffic_annotation =
14612 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014613 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214614
tfarina42834112016-09-22 13:38:2014615 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14617 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214618
14619 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214620 ASSERT_TRUE(response);
14621 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214622 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214623 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214624 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114625 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214626 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214627}
14628
bnc8016c1f2017-03-31 02:11:2914629// Regression test for https://crbug.com/546991.
14630// The server might not be able to serve an IP pooled request, and might send a
14631// 421 Misdirected Request response status to indicate this.
14632// HttpNetworkTransaction should reset the request and retry without IP pooling.
14633TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14634 // Two hosts resolve to the same IP address.
14635 const std::string ip_addr = "1.2.3.4";
14636 IPAddress ip;
14637 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14638 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14639
Jeremy Roman0579ed62017-08-29 15:56:1914640 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914641 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14642 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14643
14644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14645
14646 // Two requests on the first connection.
14647 SpdySerializedFrame req1(
14648 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14649 spdy_util_.UpdateWithStreamDestruction(1);
14650 SpdySerializedFrame req2(
14651 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14652 SpdySerializedFrame rst(
14653 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14654 MockWrite writes1[] = {
14655 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14656 CreateMockWrite(rst, 6),
14657 };
14658
14659 // The first one succeeds, the second gets error 421 Misdirected Request.
14660 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14661 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14662 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714663 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914664 SpdySerializedFrame resp2(
14665 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14666 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14667 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14668
14669 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114670 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2914671 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14672
14673 AddSSLSocketData();
14674
14675 // Retry the second request on a second connection.
14676 SpdyTestUtil spdy_util2;
14677 SpdySerializedFrame req3(
14678 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14679 MockWrite writes2[] = {
14680 CreateMockWrite(req3, 0),
14681 };
14682
14683 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14684 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14685 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14686 MockRead(ASYNC, 0, 3)};
14687
14688 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114689 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2914690 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14691
14692 AddSSLSocketData();
14693
14694 // Preload mail.example.org into HostCache.
14695 HostPortPair host_port("mail.example.org", 443);
14696 HostResolver::RequestInfo resolve_info(host_port);
14697 AddressList ignored;
14698 std::unique_ptr<HostResolver::Request> request;
14699 TestCompletionCallback callback;
14700 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14701 &ignored, callback.callback(),
14702 &request, NetLogWithSource());
14703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14704 rv = callback.WaitForResult();
14705 EXPECT_THAT(rv, IsOk());
14706
14707 HttpRequestInfo request1;
14708 request1.method = "GET";
14709 request1.url = GURL("https://www.example.org/");
14710 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014711 request1.traffic_annotation =
14712 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914713 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14714
14715 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14717 rv = callback.WaitForResult();
14718 EXPECT_THAT(rv, IsOk());
14719
14720 const HttpResponseInfo* response = trans1.GetResponseInfo();
14721 ASSERT_TRUE(response);
14722 ASSERT_TRUE(response->headers);
14723 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14724 EXPECT_TRUE(response->was_fetched_via_spdy);
14725 EXPECT_TRUE(response->was_alpn_negotiated);
14726 std::string response_data;
14727 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14728 EXPECT_EQ("hello!", response_data);
14729
14730 HttpRequestInfo request2;
14731 request2.method = "GET";
14732 request2.url = GURL("https://mail.example.org/");
14733 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014734 request2.traffic_annotation =
14735 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914736 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14737
14738 BoundTestNetLog log;
14739 rv = trans2.Start(&request2, callback.callback(), log.bound());
14740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14741 rv = callback.WaitForResult();
14742 EXPECT_THAT(rv, IsOk());
14743
14744 response = trans2.GetResponseInfo();
14745 ASSERT_TRUE(response);
14746 ASSERT_TRUE(response->headers);
14747 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14748 EXPECT_TRUE(response->was_fetched_via_spdy);
14749 EXPECT_TRUE(response->was_alpn_negotiated);
14750 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14751 EXPECT_EQ("hello!", response_data);
14752
14753 TestNetLogEntry::List entries;
14754 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914755 ExpectLogContainsSomewhere(
14756 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914757 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914758}
14759
14760// Test that HTTP 421 responses are properly returned to the caller if received
14761// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14762// portions of the response.
14763TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14764 // Two hosts resolve to the same IP address.
14765 const std::string ip_addr = "1.2.3.4";
14766 IPAddress ip;
14767 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14768 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14769
Jeremy Roman0579ed62017-08-29 15:56:1914770 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914771 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14772 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14773
14774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14775
14776 // Two requests on the first connection.
14777 SpdySerializedFrame req1(
14778 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14779 spdy_util_.UpdateWithStreamDestruction(1);
14780 SpdySerializedFrame req2(
14781 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14782 SpdySerializedFrame rst(
14783 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14784 MockWrite writes1[] = {
14785 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14786 CreateMockWrite(rst, 6),
14787 };
14788
14789 // The first one succeeds, the second gets error 421 Misdirected Request.
14790 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14791 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14792 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714793 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914794 SpdySerializedFrame resp2(
14795 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14796 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14797 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14798
14799 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114800 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5914801 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14802
14803 AddSSLSocketData();
14804
14805 // Retry the second request on a second connection. It returns 421 Misdirected
14806 // Retry again.
14807 SpdyTestUtil spdy_util2;
14808 SpdySerializedFrame req3(
14809 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14810 MockWrite writes2[] = {
14811 CreateMockWrite(req3, 0),
14812 };
14813
14814 SpdySerializedFrame resp3(
14815 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14816 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14817 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14818 MockRead(ASYNC, 0, 3)};
14819
14820 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114821 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5914822 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14823
14824 AddSSLSocketData();
14825
14826 // Preload mail.example.org into HostCache.
14827 HostPortPair host_port("mail.example.org", 443);
14828 HostResolver::RequestInfo resolve_info(host_port);
14829 AddressList ignored;
14830 std::unique_ptr<HostResolver::Request> request;
14831 TestCompletionCallback callback;
14832 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14833 &ignored, callback.callback(),
14834 &request, NetLogWithSource());
14835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14836 rv = callback.WaitForResult();
14837 EXPECT_THAT(rv, IsOk());
14838
14839 HttpRequestInfo request1;
14840 request1.method = "GET";
14841 request1.url = GURL("https://www.example.org/");
14842 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014843 request1.traffic_annotation =
14844 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914845 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14846
14847 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14849 rv = callback.WaitForResult();
14850 EXPECT_THAT(rv, IsOk());
14851
14852 const HttpResponseInfo* response = trans1.GetResponseInfo();
14853 ASSERT_TRUE(response);
14854 ASSERT_TRUE(response->headers);
14855 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14856 EXPECT_TRUE(response->was_fetched_via_spdy);
14857 EXPECT_TRUE(response->was_alpn_negotiated);
14858 std::string response_data;
14859 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14860 EXPECT_EQ("hello!", response_data);
14861
14862 HttpRequestInfo request2;
14863 request2.method = "GET";
14864 request2.url = GURL("https://mail.example.org/");
14865 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014866 request2.traffic_annotation =
14867 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914868 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14869
14870 BoundTestNetLog log;
14871 rv = trans2.Start(&request2, callback.callback(), log.bound());
14872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14873 rv = callback.WaitForResult();
14874 EXPECT_THAT(rv, IsOk());
14875
14876 // After a retry, the 421 Misdirected Request is reported back up to the
14877 // caller.
14878 response = trans2.GetResponseInfo();
14879 ASSERT_TRUE(response);
14880 ASSERT_TRUE(response->headers);
14881 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14882 EXPECT_TRUE(response->was_fetched_via_spdy);
14883 EXPECT_TRUE(response->was_alpn_negotiated);
14884 EXPECT_TRUE(response->ssl_info.cert);
14885 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14886 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914887}
14888
bnc6dcd8192017-05-25 20:11:5014889class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614890 public:
14891 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014892 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714893 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614894
dchengb03027d2014-10-21 12:00:2014895 int ResolveFromCache(const RequestInfo& info,
14896 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014897 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014898 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014899 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014900 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614901 return rv;
14902 }
14903
[email protected]e3ceb682011-06-28 23:55:4614904 private:
[email protected]e3ceb682011-06-28 23:55:4614905 const HostPortPair host_port_;
14906};
14907
bncd16676a2016-07-20 16:23:0114908TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314909 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614910 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914911 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714912 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914913 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614914
bnc032658ba2016-09-26 18:17:1514915 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614916
bncdf80d44fd2016-07-15 20:27:4114917 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914918 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814919 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114920 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714921 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614922 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114923 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614924 };
bnc42331402016-07-25 13:36:1514925 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114926 SpdySerializedFrame host1_resp_body(
14927 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514928 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114929 SpdySerializedFrame host2_resp_body(
14930 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614931 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114932 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14933 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314934 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614935 };
14936
eroman36d84e54432016-03-17 03:23:0214937 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214938 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114939 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714940 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614941
[email protected]aa22b242011-11-16 18:58:2914942 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614943 HttpRequestInfo request1;
14944 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314945 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614946 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014947 request1.traffic_annotation =
14948 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014949 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614950
tfarina42834112016-09-22 13:38:2014951 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114952 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14953 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614954
14955 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214956 ASSERT_TRUE(response);
14957 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214958 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614959
14960 std::string response_data;
robpercival214763f2016-07-01 23:27:0114961 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614962 EXPECT_EQ("hello!", response_data);
14963
14964 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714965 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614966 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014967 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014968 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14969 &ignored, callback.callback(),
14970 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714972 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114973 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614974
14975 HttpRequestInfo request2;
14976 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714977 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614978 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014979 request2.traffic_annotation =
14980 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014981 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614982
tfarina42834112016-09-22 13:38:2014983 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14985 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614986
14987 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214988 ASSERT_TRUE(response);
14989 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214990 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614991 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214992 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114993 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614994 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614995}
14996
bncd16676a2016-07-20 16:23:0114997TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314998 const std::string https_url = "https://www.example.org:8080/";
14999 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415000
15001 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115002 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915003 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415004
15005 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115006 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415007 };
15008
bnc42331402016-07-25 13:36:1515009 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115010 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15011 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915012 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415013
Ryan Sleevib8d7ea02018-05-07 20:01:0115014 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415015 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715016 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415017
15018 // HTTP GET for the HTTP URL
15019 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315020 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415021 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315022 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415023 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415024 };
15025
15026 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315027 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15028 MockRead(ASYNC, 2, "hello"),
15029 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415030 };
15031
Ryan Sleevib8d7ea02018-05-07 20:01:0115032 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415033
[email protected]8450d722012-07-02 19:14:0415034 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615035 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15037 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15038 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415039
danakj1fd259a02016-04-16 03:17:0915040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415041
15042 // Start the first transaction to set up the SpdySession
15043 HttpRequestInfo request1;
15044 request1.method = "GET";
15045 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415046 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015047 request1.traffic_annotation =
15048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015049 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415050 TestCompletionCallback callback1;
15051 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015052 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515053 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415054
robpercival214763f2016-07-01 23:27:0115055 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415056 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15057
15058 // Now, start the HTTP request
15059 HttpRequestInfo request2;
15060 request2.method = "GET";
15061 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415062 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015063 request2.traffic_annotation =
15064 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015065 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415066 TestCompletionCallback callback2;
15067 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015068 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515069 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415070
robpercival214763f2016-07-01 23:27:0115071 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415072 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15073}
15074
bnc5452e2a2015-05-08 16:27:4215075// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15076// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115077TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515078 url::SchemeHostPort server("https", "www.example.org", 443);
15079 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215080
bnc8bef8da22016-05-30 01:28:2515081 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215082 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615083 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215084 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15085
15086 // No data should be read from the alternative, because HTTP/1.1 is
15087 // negotiated.
15088 StaticSocketDataProvider data;
15089 session_deps_.socket_factory->AddSocketDataProvider(&data);
15090
15091 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615092 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215093 // mocked. This way the request relies on the alternate Job.
15094 StaticSocketDataProvider data_refused;
15095 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15096 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15097
zhongyi3d4a55e72016-04-22 20:36:4615098 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015100 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215101 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115102 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215103 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115104 http_server_properties->SetHttp2AlternativeService(
15105 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215106
bnc5452e2a2015-05-08 16:27:4215107 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615108 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215109 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515110 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1015111 request.traffic_annotation =
15112 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215113 TestCompletionCallback callback;
15114
15115 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215116 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015117 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215118 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215119}
15120
bnc40448a532015-05-11 19:13:1415121// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615122// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415123// succeeds, the request should succeed, even if the latter fails because
15124// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115125TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515126 url::SchemeHostPort server("https", "www.example.org", 443);
15127 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415128
15129 // Negotiate HTTP/1.1 with alternative.
15130 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615131 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415132 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15133
15134 // No data should be read from the alternative, because HTTP/1.1 is
15135 // negotiated.
15136 StaticSocketDataProvider data;
15137 session_deps_.socket_factory->AddSocketDataProvider(&data);
15138
zhongyi3d4a55e72016-04-22 20:36:4615139 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415140 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615141 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415142 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15143
15144 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515145 MockWrite("GET / HTTP/1.1\r\n"
15146 "Host: www.example.org\r\n"
15147 "Connection: keep-alive\r\n\r\n"),
15148 MockWrite("GET /second HTTP/1.1\r\n"
15149 "Host: www.example.org\r\n"
15150 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415151 };
15152
15153 MockRead http_reads[] = {
15154 MockRead("HTTP/1.1 200 OK\r\n"),
15155 MockRead("Content-Type: text/html\r\n"),
15156 MockRead("Content-Length: 6\r\n\r\n"),
15157 MockRead("foobar"),
15158 MockRead("HTTP/1.1 200 OK\r\n"),
15159 MockRead("Content-Type: text/html\r\n"),
15160 MockRead("Content-Length: 7\r\n\r\n"),
15161 MockRead("another"),
15162 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115163 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1415164 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15165
zhongyi3d4a55e72016-04-22 20:36:4615166 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015168 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415169 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115170 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215171 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115172 http_server_properties->SetHttp2AlternativeService(
15173 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415174
15175 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15176 HttpRequestInfo request1;
15177 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515178 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415179 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015180 request1.traffic_annotation =
15181 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415182 TestCompletionCallback callback1;
15183
tfarina42834112016-09-22 13:38:2015184 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415185 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115186 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415187
15188 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215189 ASSERT_TRUE(response1);
15190 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415191 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15192
15193 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115194 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415195 EXPECT_EQ("foobar", response_data1);
15196
15197 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15198 // for alternative service.
15199 EXPECT_TRUE(
15200 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15201
zhongyi3d4a55e72016-04-22 20:36:4615202 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415203 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615204 // to server.
bnc40448a532015-05-11 19:13:1415205 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15206 HttpRequestInfo request2;
15207 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515208 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415209 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015210 request2.traffic_annotation =
15211 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415212 TestCompletionCallback callback2;
15213
tfarina42834112016-09-22 13:38:2015214 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415215 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115216 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415217
15218 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215219 ASSERT_TRUE(response2);
15220 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415221 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15222
15223 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115224 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415225 EXPECT_EQ("another", response_data2);
15226}
15227
bnc5452e2a2015-05-08 16:27:4215228// Alternative service requires HTTP/2 (or SPDY), but there is already a
15229// HTTP/1.1 socket open to the alternative server. That socket should not be
15230// used.
bncd16676a2016-07-20 16:23:0115231TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615232 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215233 HostPortPair alternative("alternative.example.org", 443);
15234 std::string origin_url = "https://origin.example.org:443";
15235 std::string alternative_url = "https://alternative.example.org:443";
15236
15237 // Negotiate HTTP/1.1 with alternative.example.org.
15238 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615239 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15241
15242 // HTTP/1.1 data for |request1| and |request2|.
15243 MockWrite http_writes[] = {
15244 MockWrite(
15245 "GET / HTTP/1.1\r\n"
15246 "Host: alternative.example.org\r\n"
15247 "Connection: keep-alive\r\n\r\n"),
15248 MockWrite(
15249 "GET / HTTP/1.1\r\n"
15250 "Host: alternative.example.org\r\n"
15251 "Connection: keep-alive\r\n\r\n"),
15252 };
15253
15254 MockRead http_reads[] = {
15255 MockRead(
15256 "HTTP/1.1 200 OK\r\n"
15257 "Content-Type: text/html; charset=iso-8859-1\r\n"
15258 "Content-Length: 40\r\n\r\n"
15259 "first HTTP/1.1 response from alternative"),
15260 MockRead(
15261 "HTTP/1.1 200 OK\r\n"
15262 "Content-Type: text/html; charset=iso-8859-1\r\n"
15263 "Content-Length: 41\r\n\r\n"
15264 "second HTTP/1.1 response from alternative"),
15265 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115266 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4215267 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15268
15269 // This test documents that an alternate Job should not pool to an already
15270 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615271 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215272 StaticSocketDataProvider data_refused;
15273 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15274 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15275
zhongyi3d4a55e72016-04-22 20:36:4615276 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015278 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215279 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115280 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215281 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115282 http_server_properties->SetHttp2AlternativeService(
15283 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215284
15285 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215286 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615287 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215288 request1.method = "GET";
15289 request1.url = GURL(alternative_url);
15290 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015291 request1.traffic_annotation =
15292 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215293 TestCompletionCallback callback1;
15294
tfarina42834112016-09-22 13:38:2015295 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115296 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615297 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215298 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215299 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215300 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215301 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215302 EXPECT_FALSE(response1->was_fetched_via_spdy);
15303 std::string response_data1;
bnc691fda62016-08-12 00:43:1615304 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215305 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15306
15307 // Request for origin.example.org, which has an alternative service. This
15308 // will start two Jobs: the alternative looks for connections to pool to,
15309 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615310 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215311 // this request fails.
bnc5452e2a2015-05-08 16:27:4215312 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615313 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215314 request2.method = "GET";
15315 request2.url = GURL(origin_url);
15316 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015317 request2.traffic_annotation =
15318 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215319 TestCompletionCallback callback2;
15320
tfarina42834112016-09-22 13:38:2015321 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115322 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215323
15324 // Another transaction to alternative. This is to test that the HTTP/1.1
15325 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215326 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615327 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215328 request3.method = "GET";
15329 request3.url = GURL(alternative_url);
15330 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015331 request3.traffic_annotation =
15332 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215333 TestCompletionCallback callback3;
15334
tfarina42834112016-09-22 13:38:2015335 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115336 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615337 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215338 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215339 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215340 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215341 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215342 EXPECT_FALSE(response3->was_fetched_via_spdy);
15343 std::string response_data3;
bnc691fda62016-08-12 00:43:1615344 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215345 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15346}
15347
bncd16676a2016-07-20 16:23:0115348TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315349 const std::string https_url = "https://www.example.org:8080/";
15350 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415351
rdsmithebb50aa2015-11-12 03:44:3815352 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115353 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815354
[email protected]8450d722012-07-02 19:14:0415355 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315356 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115357 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415358 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115359 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915360 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115361 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215362 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915363
15364 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915365 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715366 req2_block[kHttp2MethodHeader] = "GET";
15367 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15368 req2_block[kHttp2SchemeHeader] = "http";
15369 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115370 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515371 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415372
15373 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115374 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15375 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415376 };
15377
bncdf80d44fd2016-07-15 20:27:4115378 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515379 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115380 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515381 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115382 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15383 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815384 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115385 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815386 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515387 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115388 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315389 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115390 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315391 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115392 CreateMockRead(wrapped_resp1, 4),
15393 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315394 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115395 CreateMockRead(resp2, 8),
15396 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315397 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15398 };
[email protected]8450d722012-07-02 19:14:0415399
Ryan Sleevib8d7ea02018-05-07 20:01:0115400 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415401 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715402 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415403
Lily Houghton8c2f97d2018-01-22 05:06:5915404 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915405 ProxyResolutionService::CreateFixedFromPacResult(
15406 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115407 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715408 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415409 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615410 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315411 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415412 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615413 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315414 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15415 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415416
danakj1fd259a02016-04-16 03:17:0915417 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415418
15419 // Start the first transaction to set up the SpdySession
15420 HttpRequestInfo request1;
15421 request1.method = "GET";
15422 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415423 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015424 request1.traffic_annotation =
15425 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015426 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415427 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015428 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415429
mmenke666a6fea2015-12-19 04:16:3315430 // This pause is a hack to avoid running into https://crbug.com/497228.
15431 data1.RunUntilPaused();
15432 base::RunLoop().RunUntilIdle();
15433 data1.Resume();
robpercival214763f2016-07-01 23:27:0115434 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415435 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15436
[email protected]f6c63db52013-02-02 00:35:2215437 LoadTimingInfo load_timing_info1;
15438 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15439 TestLoadTimingNotReusedWithPac(load_timing_info1,
15440 CONNECT_TIMING_HAS_SSL_TIMES);
15441
mmenke666a6fea2015-12-19 04:16:3315442 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415443 HttpRequestInfo request2;
15444 request2.method = "GET";
15445 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415446 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015447 request2.traffic_annotation =
15448 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015449 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415450 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015451 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415452
mmenke666a6fea2015-12-19 04:16:3315453 // This pause is a hack to avoid running into https://crbug.com/497228.
15454 data1.RunUntilPaused();
15455 base::RunLoop().RunUntilIdle();
15456 data1.Resume();
robpercival214763f2016-07-01 23:27:0115457 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315458
[email protected]8450d722012-07-02 19:14:0415459 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215460
15461 LoadTimingInfo load_timing_info2;
15462 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15463 // The established SPDY sessions is considered reused by the HTTP request.
15464 TestLoadTimingReusedWithPac(load_timing_info2);
15465 // HTTP requests over a SPDY session should have a different connection
15466 // socket_log_id than requests over a tunnel.
15467 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415468}
15469
[email protected]2d88e7d2012-07-19 17:55:1715470// Test that in the case where we have a SPDY session to a SPDY proxy
15471// that we do not pool other origins that resolve to the same IP when
15472// the certificate does not match the new origin.
15473// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115474TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315475 const std::string url1 = "http://www.example.org/";
15476 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715477 const std::string ip_addr = "1.2.3.4";
15478
rdsmithebb50aa2015-11-12 03:44:3815479 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115480 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815481
[email protected]2d88e7d2012-07-19 17:55:1715482 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615483 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315484 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115485 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515486 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715487
15488 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115489 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715490 };
15491
bnc42331402016-07-25 13:36:1515492 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115493 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715494 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115495 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15496 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715497 };
15498
Ryan Sleevib8d7ea02018-05-07 20:01:0115499 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3215500 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915501 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715502 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15503 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315504 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715505
15506 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115507 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915508 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715509
15510 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115511 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715512 };
15513
bnc42331402016-07-25 13:36:1515514 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115515 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15516 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315517 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715518
Ryan Sleevib8d7ea02018-05-07 20:01:0115519 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1715520 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315521 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715522
15523 // Set up a proxy config that sends HTTP requests to a proxy, and
15524 // all others direct.
15525 ProxyConfig proxy_config;
15526 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915527 session_deps_.proxy_resolution_service =
15528 std::make_unique<ProxyResolutionService>(
15529 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15530 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15531 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715532
bncce36dca22015-04-21 22:11:2315533 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615534 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715535 // Load a valid cert. Note, that this does not need to
15536 // be valid for proxy because the MockSSLClientSocket does
15537 // not actually verify it. But SpdySession will use this
15538 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915539 ssl1.ssl_info.cert =
15540 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15541 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315542 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15543 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715544
15545 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615546 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315547 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15548 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715549
Jeremy Roman0579ed62017-08-29 15:56:1915550 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315551 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715552 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715553
danakj1fd259a02016-04-16 03:17:0915554 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715555
15556 // Start the first transaction to set up the SpdySession
15557 HttpRequestInfo request1;
15558 request1.method = "GET";
15559 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715560 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015561 request1.traffic_annotation =
15562 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015563 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715564 TestCompletionCallback callback1;
15565 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015566 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315567 // This pause is a hack to avoid running into https://crbug.com/497228.
15568 data1.RunUntilPaused();
15569 base::RunLoop().RunUntilIdle();
15570 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715571
robpercival214763f2016-07-01 23:27:0115572 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715573 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15574
15575 // Now, start the HTTP request
15576 HttpRequestInfo request2;
15577 request2.method = "GET";
15578 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715579 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015580 request2.traffic_annotation =
15581 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015582 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715583 TestCompletionCallback callback2;
15584 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015585 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515586 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715587
15588 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115589 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715590 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15591}
15592
[email protected]85f97342013-04-17 06:12:2415593// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15594// error) in SPDY session, removes the socket from pool and closes the SPDY
15595// session. Verify that new url's from the same HttpNetworkSession (and a new
15596// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115597TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315598 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415599
15600 MockRead reads1[] = {
15601 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15602 };
15603
Ryan Sleevib8d7ea02018-05-07 20:01:0115604 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2415605
bncdf80d44fd2016-07-15 20:27:4115606 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915607 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415608 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115609 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415610 };
15611
bnc42331402016-07-25 13:36:1515612 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115613 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415614 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115615 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15616 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415617 };
15618
Ryan Sleevib8d7ea02018-05-07 20:01:0115619 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2415620
[email protected]85f97342013-04-17 06:12:2415621 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615622 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15624 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415625
15626 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615627 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15629 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415630
danakj1fd259a02016-04-16 03:17:0915631 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015632 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415633
15634 // Start the first transaction to set up the SpdySession and verify that
15635 // connection was closed.
15636 HttpRequestInfo request1;
15637 request1.method = "GET";
15638 request1.url = GURL(https_url);
15639 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015640 request1.traffic_annotation =
15641 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015642 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415643 TestCompletionCallback callback1;
15644 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015645 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115646 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415647
15648 // Now, start the second request and make sure it succeeds.
15649 HttpRequestInfo request2;
15650 request2.method = "GET";
15651 request2.url = GURL(https_url);
15652 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015653 request2.traffic_annotation =
15654 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015655 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415656 TestCompletionCallback callback2;
15657 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015658 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415659
robpercival214763f2016-07-01 23:27:0115660 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415661 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15662}
15663
bncd16676a2016-07-20 16:23:0115664TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315665 ClientSocketPoolManager::set_max_sockets_per_group(
15666 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15667 ClientSocketPoolManager::set_max_sockets_per_pool(
15668 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15669
15670 // Use two different hosts with different IPs so they don't get pooled.
15671 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15672 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315674
15675 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615676 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315677 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615678 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15680 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15681
bncdf80d44fd2016-07-15 20:27:4115682 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915683 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315684 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115685 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315686 };
bnc42331402016-07-25 13:36:1515687 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115688 SpdySerializedFrame host1_resp_body(
15689 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315690 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115691 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915692 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315693 };
15694
rdsmithebb50aa2015-11-12 03:44:3815695 // Use a separate test instance for the separate SpdySession that will be
15696 // created.
bncd16676a2016-07-20 16:23:0115697 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0115698 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1215699 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0315700
bncdf80d44fd2016-07-15 20:27:4115701 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915702 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315703 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115704 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315705 };
bnc42331402016-07-25 13:36:1515706 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115707 SpdySerializedFrame host2_resp_body(
15708 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315709 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115710 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915711 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315712 };
15713
Ryan Sleevib8d7ea02018-05-07 20:01:0115714 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1215715 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0315716
15717 MockWrite http_write[] = {
15718 MockWrite("GET / HTTP/1.1\r\n"
15719 "Host: www.a.com\r\n"
15720 "Connection: keep-alive\r\n\r\n"),
15721 };
15722
15723 MockRead http_read[] = {
15724 MockRead("HTTP/1.1 200 OK\r\n"),
15725 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15726 MockRead("Content-Length: 6\r\n\r\n"),
15727 MockRead("hello!"),
15728 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115729 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0315730 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15731
15732 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415733 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15734 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315735 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615736 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315737
15738 TestCompletionCallback callback;
15739 HttpRequestInfo request1;
15740 request1.method = "GET";
15741 request1.url = GURL("https://www.a.com/");
15742 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015743 request1.traffic_annotation =
15744 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815745 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915746 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315747
tfarina42834112016-09-22 13:38:2015748 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15750 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315751
15752 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215753 ASSERT_TRUE(response);
15754 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215755 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315756 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215757 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315758
15759 std::string response_data;
robpercival214763f2016-07-01 23:27:0115760 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315761 EXPECT_EQ("hello!", response_data);
15762 trans.reset();
15763 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615764 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315765
15766 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415767 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15768 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315769 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615770 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315771 HttpRequestInfo request2;
15772 request2.method = "GET";
15773 request2.url = GURL("https://www.b.com/");
15774 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015775 request2.traffic_annotation =
15776 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815777 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915778 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315779
tfarina42834112016-09-22 13:38:2015780 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15782 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315783
15784 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215785 ASSERT_TRUE(response);
15786 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215787 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315788 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215789 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115790 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315791 EXPECT_EQ("hello!", response_data);
15792 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615793 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315794 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615795 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315796
15797 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415798 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15799 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315800 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615801 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315802 HttpRequestInfo request3;
15803 request3.method = "GET";
15804 request3.url = GURL("http://www.a.com/");
15805 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015806 request3.traffic_annotation =
15807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815808 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915809 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315810
tfarina42834112016-09-22 13:38:2015811 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15813 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315814
15815 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215816 ASSERT_TRUE(response);
15817 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315818 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15819 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215820 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115821 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315822 EXPECT_EQ("hello!", response_data);
15823 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615824 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315825 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615826 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315827}
15828
bncd16676a2016-07-20 16:23:0115829TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415830 HttpRequestInfo request;
15831 request.method = "GET";
bncce36dca22015-04-21 22:11:2315832 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015833 request.traffic_annotation =
15834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415835
danakj1fd259a02016-04-16 03:17:0915836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415838
ttuttled9dbc652015-09-29 20:00:5915839 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415840 StaticSocketDataProvider data;
15841 data.set_connect_data(mock_connect);
15842 session_deps_.socket_factory->AddSocketDataProvider(&data);
15843
15844 TestCompletionCallback callback;
15845
tfarina42834112016-09-22 13:38:2015846 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415848
15849 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115850 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415851
[email protected]79e1fd62013-06-20 06:50:0415852 // We don't care whether this succeeds or fails, but it shouldn't crash.
15853 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615854 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715855
15856 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615857 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715858 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115859 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915860
15861 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615862 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915863 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415864}
15865
bncd16676a2016-07-20 16:23:0115866TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415867 HttpRequestInfo request;
15868 request.method = "GET";
bncce36dca22015-04-21 22:11:2315869 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015870 request.traffic_annotation =
15871 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415872
danakj1fd259a02016-04-16 03:17:0915873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415875
ttuttled9dbc652015-09-29 20:00:5915876 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415877 StaticSocketDataProvider data;
15878 data.set_connect_data(mock_connect);
15879 session_deps_.socket_factory->AddSocketDataProvider(&data);
15880
15881 TestCompletionCallback callback;
15882
tfarina42834112016-09-22 13:38:2015883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415885
15886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115887 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415888
[email protected]79e1fd62013-06-20 06:50:0415889 // We don't care whether this succeeds or fails, but it shouldn't crash.
15890 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615891 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715892
15893 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615894 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715895 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115896 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915897
15898 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615899 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915900 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415901}
15902
bncd16676a2016-07-20 16:23:0115903TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415904 HttpRequestInfo request;
15905 request.method = "GET";
bncce36dca22015-04-21 22:11:2315906 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015907 request.traffic_annotation =
15908 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415909
danakj1fd259a02016-04-16 03:17:0915910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415912
15913 MockWrite data_writes[] = {
15914 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15915 };
15916 MockRead data_reads[] = {
15917 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15918 };
15919
Ryan Sleevib8d7ea02018-05-07 20:01:0115920 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415921 session_deps_.socket_factory->AddSocketDataProvider(&data);
15922
15923 TestCompletionCallback callback;
15924
tfarina42834112016-09-22 13:38:2015925 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415927
15928 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115929 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415930
[email protected]79e1fd62013-06-20 06:50:0415931 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615932 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415933 EXPECT_TRUE(request_headers.HasHeader("Host"));
15934}
15935
bncd16676a2016-07-20 16:23:0115936TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415937 HttpRequestInfo request;
15938 request.method = "GET";
bncce36dca22015-04-21 22:11:2315939 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015940 request.traffic_annotation =
15941 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415942
danakj1fd259a02016-04-16 03:17:0915943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615944 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415945
15946 MockWrite data_writes[] = {
15947 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15948 };
15949 MockRead data_reads[] = {
15950 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15951 };
15952
Ryan Sleevib8d7ea02018-05-07 20:01:0115953 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415954 session_deps_.socket_factory->AddSocketDataProvider(&data);
15955
15956 TestCompletionCallback callback;
15957
tfarina42834112016-09-22 13:38:2015958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415960
15961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115962 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415963
[email protected]79e1fd62013-06-20 06:50:0415964 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615965 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415966 EXPECT_TRUE(request_headers.HasHeader("Host"));
15967}
15968
bncd16676a2016-07-20 16:23:0115969TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415970 HttpRequestInfo request;
15971 request.method = "GET";
bncce36dca22015-04-21 22:11:2315972 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015973 request.traffic_annotation =
15974 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415975
danakj1fd259a02016-04-16 03:17:0915976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615977 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415978
15979 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315980 MockWrite(
15981 "GET / HTTP/1.1\r\n"
15982 "Host: www.example.org\r\n"
15983 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415984 };
15985 MockRead data_reads[] = {
15986 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15987 };
15988
Ryan Sleevib8d7ea02018-05-07 20:01:0115989 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415990 session_deps_.socket_factory->AddSocketDataProvider(&data);
15991
15992 TestCompletionCallback callback;
15993
tfarina42834112016-09-22 13:38:2015994 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415996
15997 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115998 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415999
[email protected]79e1fd62013-06-20 06:50:0416000 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616001 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416002 EXPECT_TRUE(request_headers.HasHeader("Host"));
16003}
16004
bncd16676a2016-07-20 16:23:0116005TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416006 HttpRequestInfo request;
16007 request.method = "GET";
bncce36dca22015-04-21 22:11:2316008 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016009 request.traffic_annotation =
16010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416011
danakj1fd259a02016-04-16 03:17:0916012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416014
16015 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316016 MockWrite(
16017 "GET / HTTP/1.1\r\n"
16018 "Host: www.example.org\r\n"
16019 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416020 };
16021 MockRead data_reads[] = {
16022 MockRead(ASYNC, ERR_CONNECTION_RESET),
16023 };
16024
Ryan Sleevib8d7ea02018-05-07 20:01:0116025 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416026 session_deps_.socket_factory->AddSocketDataProvider(&data);
16027
16028 TestCompletionCallback callback;
16029
tfarina42834112016-09-22 13:38:2016030 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416032
16033 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116034 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416035
[email protected]79e1fd62013-06-20 06:50:0416036 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616037 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416038 EXPECT_TRUE(request_headers.HasHeader("Host"));
16039}
16040
bncd16676a2016-07-20 16:23:0116041TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416042 HttpRequestInfo request;
16043 request.method = "GET";
bncce36dca22015-04-21 22:11:2316044 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416045 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016046 request.traffic_annotation =
16047 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416048
danakj1fd259a02016-04-16 03:17:0916049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616050 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416051
16052 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316053 MockWrite(
16054 "GET / HTTP/1.1\r\n"
16055 "Host: www.example.org\r\n"
16056 "Connection: keep-alive\r\n"
16057 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416058 };
16059 MockRead data_reads[] = {
16060 MockRead("HTTP/1.1 200 OK\r\n"
16061 "Content-Length: 5\r\n\r\n"
16062 "hello"),
16063 MockRead(ASYNC, ERR_UNEXPECTED),
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, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416076
16077 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616078 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416079 std::string foo;
16080 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16081 EXPECT_EQ("bar", foo);
16082}
16083
[email protected]043b68c82013-08-22 23:41:5216084// Tests that when a used socket is returned to the SSL socket pool, it's closed
16085// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116086TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216087 ClientSocketPoolManager::set_max_sockets_per_group(
16088 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16089 ClientSocketPoolManager::set_max_sockets_per_pool(
16090 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16091
16092 // Set up SSL request.
16093
16094 HttpRequestInfo ssl_request;
16095 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316096 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016097 ssl_request.traffic_annotation =
16098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216099
16100 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316101 MockWrite(
16102 "GET / HTTP/1.1\r\n"
16103 "Host: www.example.org\r\n"
16104 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216105 };
16106 MockRead ssl_reads[] = {
16107 MockRead("HTTP/1.1 200 OK\r\n"),
16108 MockRead("Content-Length: 11\r\n\r\n"),
16109 MockRead("hello world"),
16110 MockRead(SYNCHRONOUS, OK),
16111 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116112 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5216113 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16114
16115 SSLSocketDataProvider ssl(ASYNC, OK);
16116 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16117
16118 // Set up HTTP request.
16119
16120 HttpRequestInfo http_request;
16121 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316122 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016123 http_request.traffic_annotation =
16124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216125
16126 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316127 MockWrite(
16128 "GET / HTTP/1.1\r\n"
16129 "Host: www.example.org\r\n"
16130 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216131 };
16132 MockRead http_reads[] = {
16133 MockRead("HTTP/1.1 200 OK\r\n"),
16134 MockRead("Content-Length: 7\r\n\r\n"),
16135 MockRead("falafel"),
16136 MockRead(SYNCHRONOUS, OK),
16137 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116138 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216139 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16140
danakj1fd259a02016-04-16 03:17:0916141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216142
16143 // Start the SSL request.
16144 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616145 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016146 ASSERT_EQ(ERR_IO_PENDING,
16147 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16148 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216149
16150 // Start the HTTP request. Pool should stall.
16151 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616152 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016153 ASSERT_EQ(ERR_IO_PENDING,
16154 http_trans.Start(&http_request, http_callback.callback(),
16155 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116156 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216157
16158 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116159 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216160 std::string response_data;
bnc691fda62016-08-12 00:43:1616161 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216162 EXPECT_EQ("hello world", response_data);
16163
16164 // The SSL socket should automatically be closed, so the HTTP request can
16165 // start.
dcheng48459ac22014-08-26 00:46:4116166 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16167 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216168
16169 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116170 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616171 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216172 EXPECT_EQ("falafel", response_data);
16173
dcheng48459ac22014-08-26 00:46:4116174 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216175}
16176
16177// Tests that when a SSL connection is established but there's no corresponding
16178// request that needs it, the new socket is closed if the transport socket pool
16179// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116180TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216181 ClientSocketPoolManager::set_max_sockets_per_group(
16182 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16183 ClientSocketPoolManager::set_max_sockets_per_pool(
16184 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16185
16186 // Set up an ssl request.
16187
16188 HttpRequestInfo ssl_request;
16189 ssl_request.method = "GET";
16190 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1016191 ssl_request.traffic_annotation =
16192 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216193
16194 // No data will be sent on the SSL socket.
16195 StaticSocketDataProvider ssl_data;
16196 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16197
16198 SSLSocketDataProvider ssl(ASYNC, OK);
16199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16200
16201 // Set up HTTP request.
16202
16203 HttpRequestInfo http_request;
16204 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316205 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016206 http_request.traffic_annotation =
16207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216208
16209 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316210 MockWrite(
16211 "GET / HTTP/1.1\r\n"
16212 "Host: www.example.org\r\n"
16213 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216214 };
16215 MockRead http_reads[] = {
16216 MockRead("HTTP/1.1 200 OK\r\n"),
16217 MockRead("Content-Length: 7\r\n\r\n"),
16218 MockRead("falafel"),
16219 MockRead(SYNCHRONOUS, OK),
16220 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116221 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216222 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16223
danakj1fd259a02016-04-16 03:17:0916224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216225
16226 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16227 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916228 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916229 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116230 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216231
16232 // Start the HTTP request. Pool should stall.
16233 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616234 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016235 ASSERT_EQ(ERR_IO_PENDING,
16236 http_trans.Start(&http_request, http_callback.callback(),
16237 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116238 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216239
16240 // The SSL connection will automatically be closed once the connection is
16241 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116242 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216243 std::string response_data;
bnc691fda62016-08-12 00:43:1616244 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216245 EXPECT_EQ("falafel", response_data);
16246
dcheng48459ac22014-08-26 00:46:4116247 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216248}
16249
bncd16676a2016-07-20 16:23:0116250TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916251 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216252 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916253 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216254 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416255
16256 HttpRequestInfo request;
16257 request.method = "POST";
16258 request.url = GURL("http://www.foo.com/");
16259 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016260 request.traffic_annotation =
16261 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416262
danakj1fd259a02016-04-16 03:17:0916263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616264 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416265 // Send headers successfully, but get an error while sending the body.
16266 MockWrite data_writes[] = {
16267 MockWrite("POST / HTTP/1.1\r\n"
16268 "Host: www.foo.com\r\n"
16269 "Connection: keep-alive\r\n"
16270 "Content-Length: 3\r\n\r\n"),
16271 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16272 };
16273
16274 MockRead data_reads[] = {
16275 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16276 MockRead("hello world"),
16277 MockRead(SYNCHRONOUS, OK),
16278 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116279 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416280 session_deps_.socket_factory->AddSocketDataProvider(&data);
16281
16282 TestCompletionCallback callback;
16283
tfarina42834112016-09-22 13:38:2016284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416286
16287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116288 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416289
bnc691fda62016-08-12 00:43:1616290 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216291 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416292
wezca1070932016-05-26 20:30:5216293 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416294 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16295
16296 std::string response_data;
bnc691fda62016-08-12 00:43:1616297 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116298 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416299 EXPECT_EQ("hello world", response_data);
16300}
16301
16302// This test makes sure the retry logic doesn't trigger when reading an error
16303// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116304TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416305 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916306 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416307 MockWrite data_writes[] = {
16308 MockWrite("GET / HTTP/1.1\r\n"
16309 "Host: www.foo.com\r\n"
16310 "Connection: keep-alive\r\n\r\n"),
16311 MockWrite("POST / HTTP/1.1\r\n"
16312 "Host: www.foo.com\r\n"
16313 "Connection: keep-alive\r\n"
16314 "Content-Length: 3\r\n\r\n"),
16315 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16316 };
16317
16318 MockRead data_reads[] = {
16319 MockRead("HTTP/1.1 200 Peachy\r\n"
16320 "Content-Length: 14\r\n\r\n"),
16321 MockRead("first response"),
16322 MockRead("HTTP/1.1 400 Not OK\r\n"
16323 "Content-Length: 15\r\n\r\n"),
16324 MockRead("second response"),
16325 MockRead(SYNCHRONOUS, OK),
16326 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116327 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416328 session_deps_.socket_factory->AddSocketDataProvider(&data);
16329
16330 TestCompletionCallback callback;
16331 HttpRequestInfo request1;
16332 request1.method = "GET";
16333 request1.url = GURL("http://www.foo.com/");
16334 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016335 request1.traffic_annotation =
16336 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416337
bnc87dcefc2017-05-25 12:47:5816338 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916339 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016340 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416342
16343 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116344 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416345
16346 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216347 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416348
wezca1070932016-05-26 20:30:5216349 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416350 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16351
16352 std::string response_data1;
16353 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116354 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416355 EXPECT_EQ("first response", response_data1);
16356 // Delete the transaction to release the socket back into the socket pool.
16357 trans1.reset();
16358
danakj1fd259a02016-04-16 03:17:0916359 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216360 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916361 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216362 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416363
16364 HttpRequestInfo request2;
16365 request2.method = "POST";
16366 request2.url = GURL("http://www.foo.com/");
16367 request2.upload_data_stream = &upload_data_stream;
16368 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016369 request2.traffic_annotation =
16370 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416371
bnc691fda62016-08-12 00:43:1616372 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016373 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416375
16376 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116377 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416378
bnc691fda62016-08-12 00:43:1616379 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216380 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416381
wezca1070932016-05-26 20:30:5216382 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416383 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16384
16385 std::string response_data2;
bnc691fda62016-08-12 00:43:1616386 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116387 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416388 EXPECT_EQ("second response", response_data2);
16389}
16390
bncd16676a2016-07-20 16:23:0116391TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416392 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916393 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216394 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916395 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216396 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416397
16398 HttpRequestInfo request;
16399 request.method = "POST";
16400 request.url = GURL("http://www.foo.com/");
16401 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016402 request.traffic_annotation =
16403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416404
danakj1fd259a02016-04-16 03:17:0916405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416407 // Send headers successfully, but get an error while sending the body.
16408 MockWrite data_writes[] = {
16409 MockWrite("POST / HTTP/1.1\r\n"
16410 "Host: www.foo.com\r\n"
16411 "Connection: keep-alive\r\n"
16412 "Content-Length: 3\r\n\r\n"
16413 "fo"),
16414 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16415 };
16416
16417 MockRead data_reads[] = {
16418 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16419 MockRead("hello world"),
16420 MockRead(SYNCHRONOUS, OK),
16421 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116422 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416423 session_deps_.socket_factory->AddSocketDataProvider(&data);
16424
16425 TestCompletionCallback callback;
16426
tfarina42834112016-09-22 13:38:2016427 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416429
16430 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116431 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416432
bnc691fda62016-08-12 00:43:1616433 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216434 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416435
wezca1070932016-05-26 20:30:5216436 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416437 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16438
16439 std::string response_data;
bnc691fda62016-08-12 00:43:1616440 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116441 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416442 EXPECT_EQ("hello world", response_data);
16443}
16444
16445// This tests the more common case than the previous test, where headers and
16446// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116447TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716448 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416449
16450 HttpRequestInfo request;
16451 request.method = "POST";
16452 request.url = GURL("http://www.foo.com/");
16453 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016454 request.traffic_annotation =
16455 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416456
danakj1fd259a02016-04-16 03:17:0916457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416459 // Send headers successfully, but get an error while sending the body.
16460 MockWrite data_writes[] = {
16461 MockWrite("POST / HTTP/1.1\r\n"
16462 "Host: www.foo.com\r\n"
16463 "Connection: keep-alive\r\n"
16464 "Transfer-Encoding: chunked\r\n\r\n"),
16465 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16466 };
16467
16468 MockRead data_reads[] = {
16469 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16470 MockRead("hello world"),
16471 MockRead(SYNCHRONOUS, OK),
16472 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116473 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416474 session_deps_.socket_factory->AddSocketDataProvider(&data);
16475
16476 TestCompletionCallback callback;
16477
tfarina42834112016-09-22 13:38:2016478 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416480 // Make sure the headers are sent before adding a chunk. This ensures that
16481 // they can't be merged with the body in a single send. Not currently
16482 // necessary since a chunked body is never merged with headers, but this makes
16483 // the test more future proof.
16484 base::RunLoop().RunUntilIdle();
16485
mmenkecbc2b712014-10-09 20:29:0716486 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416487
16488 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116489 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416490
bnc691fda62016-08-12 00:43:1616491 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216492 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416493
wezca1070932016-05-26 20:30:5216494 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416495 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16496
16497 std::string response_data;
bnc691fda62016-08-12 00:43:1616498 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116499 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416500 EXPECT_EQ("hello world", response_data);
16501}
16502
bncd16676a2016-07-20 16:23:0116503TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916504 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216505 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916506 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216507 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416508
16509 HttpRequestInfo request;
16510 request.method = "POST";
16511 request.url = GURL("http://www.foo.com/");
16512 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016513 request.traffic_annotation =
16514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416515
danakj1fd259a02016-04-16 03:17:0916516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416518
16519 MockWrite data_writes[] = {
16520 MockWrite("POST / HTTP/1.1\r\n"
16521 "Host: www.foo.com\r\n"
16522 "Connection: keep-alive\r\n"
16523 "Content-Length: 3\r\n\r\n"),
16524 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16525 };
16526
16527 MockRead data_reads[] = {
16528 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16529 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16530 MockRead("hello world"),
16531 MockRead(SYNCHRONOUS, OK),
16532 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116533 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416534 session_deps_.socket_factory->AddSocketDataProvider(&data);
16535
16536 TestCompletionCallback callback;
16537
tfarina42834112016-09-22 13:38:2016538 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416540
16541 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116542 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416543
bnc691fda62016-08-12 00:43:1616544 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216545 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416546
wezca1070932016-05-26 20:30:5216547 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416548 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16549
16550 std::string response_data;
bnc691fda62016-08-12 00:43:1616551 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116552 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416553 EXPECT_EQ("hello world", response_data);
16554}
16555
bncd16676a2016-07-20 16:23:0116556TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916557 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216558 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916559 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216560 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416561
16562 HttpRequestInfo request;
16563 request.method = "POST";
16564 request.url = GURL("http://www.foo.com/");
16565 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016566 request.traffic_annotation =
16567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416568
danakj1fd259a02016-04-16 03:17:0916569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416571 // Send headers successfully, but get an error while sending the body.
16572 MockWrite data_writes[] = {
16573 MockWrite("POST / HTTP/1.1\r\n"
16574 "Host: www.foo.com\r\n"
16575 "Connection: keep-alive\r\n"
16576 "Content-Length: 3\r\n\r\n"),
16577 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16578 };
16579
16580 MockRead data_reads[] = {
16581 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16582 MockRead("hello world"),
16583 MockRead(SYNCHRONOUS, OK),
16584 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116585 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416586 session_deps_.socket_factory->AddSocketDataProvider(&data);
16587
16588 TestCompletionCallback callback;
16589
tfarina42834112016-09-22 13:38:2016590 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116591 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416592
16593 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116594 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416595}
16596
bncd16676a2016-07-20 16:23:0116597TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416598 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916599 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216600 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916601 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216602 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416603
16604 HttpRequestInfo request;
16605 request.method = "POST";
16606 request.url = GURL("http://www.foo.com/");
16607 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016608 request.traffic_annotation =
16609 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416610
danakj1fd259a02016-04-16 03:17:0916611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416613 // Send headers successfully, but get an error while sending the body.
16614 MockWrite data_writes[] = {
16615 MockWrite("POST / HTTP/1.1\r\n"
16616 "Host: www.foo.com\r\n"
16617 "Connection: keep-alive\r\n"
16618 "Content-Length: 3\r\n\r\n"),
16619 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16620 };
16621
16622 MockRead data_reads[] = {
16623 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16624 MockRead("HTTP/1.0 302 Redirect\r\n"),
16625 MockRead("Location: http://somewhere-else.com/\r\n"),
16626 MockRead("Content-Length: 0\r\n\r\n"),
16627 MockRead(SYNCHRONOUS, OK),
16628 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116629 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416630 session_deps_.socket_factory->AddSocketDataProvider(&data);
16631
16632 TestCompletionCallback callback;
16633
tfarina42834112016-09-22 13:38:2016634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416636
16637 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116638 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416639}
16640
bncd16676a2016-07-20 16:23:0116641TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916642 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216643 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916644 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216645 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416646
16647 HttpRequestInfo request;
16648 request.method = "POST";
16649 request.url = GURL("http://www.foo.com/");
16650 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016651 request.traffic_annotation =
16652 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416653
danakj1fd259a02016-04-16 03:17:0916654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416656 // Send headers successfully, but get an error while sending the body.
16657 MockWrite data_writes[] = {
16658 MockWrite("POST / HTTP/1.1\r\n"
16659 "Host: www.foo.com\r\n"
16660 "Connection: keep-alive\r\n"
16661 "Content-Length: 3\r\n\r\n"),
16662 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16663 };
16664
16665 MockRead data_reads[] = {
16666 MockRead("HTTP 0.9 rocks!"),
16667 MockRead(SYNCHRONOUS, OK),
16668 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116669 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416670 session_deps_.socket_factory->AddSocketDataProvider(&data);
16671
16672 TestCompletionCallback callback;
16673
tfarina42834112016-09-22 13:38:2016674 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416676
16677 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116678 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416679}
16680
bncd16676a2016-07-20 16:23:0116681TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916682 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216683 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916684 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216685 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416686
16687 HttpRequestInfo request;
16688 request.method = "POST";
16689 request.url = GURL("http://www.foo.com/");
16690 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016691 request.traffic_annotation =
16692 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416693
danakj1fd259a02016-04-16 03:17:0916694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616695 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416696 // Send headers successfully, but get an error while sending the body.
16697 MockWrite data_writes[] = {
16698 MockWrite("POST / HTTP/1.1\r\n"
16699 "Host: www.foo.com\r\n"
16700 "Connection: keep-alive\r\n"
16701 "Content-Length: 3\r\n\r\n"),
16702 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16703 };
16704
16705 MockRead data_reads[] = {
16706 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16707 MockRead(SYNCHRONOUS, OK),
16708 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116709 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416710 session_deps_.socket_factory->AddSocketDataProvider(&data);
16711
16712 TestCompletionCallback callback;
16713
tfarina42834112016-09-22 13:38:2016714 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416716
16717 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116718 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416719}
16720
Bence Békydca6bd92018-01-30 13:43:0616721#if BUILDFLAG(ENABLE_WEBSOCKETS)
16722
16723namespace {
16724
16725void AddWebSocketHeaders(HttpRequestHeaders* headers) {
16726 headers->SetHeader("Connection", "Upgrade");
16727 headers->SetHeader("Upgrade", "websocket");
16728 headers->SetHeader("Origin", "http://www.example.org");
16729 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0616730}
16731
16732} // namespace
16733
16734TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0116735 for (bool secure : {true, false}) {
16736 MockWrite data_writes[] = {
16737 MockWrite("GET / HTTP/1.1\r\n"
16738 "Host: www.example.org\r\n"
16739 "Connection: Upgrade\r\n"
16740 "Upgrade: websocket\r\n"
16741 "Origin: http://www.example.org\r\n"
16742 "Sec-WebSocket-Version: 13\r\n"
16743 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16744 "Sec-WebSocket-Extensions: permessage-deflate; "
16745 "client_max_window_bits\r\n\r\n")};
16746
16747 MockRead data_reads[] = {
16748 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16749 "Upgrade: websocket\r\n"
16750 "Connection: Upgrade\r\n"
16751 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
16752
Ryan Sleevib8d7ea02018-05-07 20:01:0116753 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0116754 session_deps_.socket_factory->AddSocketDataProvider(&data);
16755 SSLSocketDataProvider ssl(ASYNC, OK);
16756 if (secure)
16757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0616758
16759 HttpRequestInfo request;
16760 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0116761 request.url =
16762 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
16763 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e62018-02-07 07:41:1016764 request.traffic_annotation =
16765 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0616766
Bence Béky2fcf4fa2018-04-06 20:06:0116767 TestWebSocketHandshakeStreamCreateHelper
16768 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1516769
Bence Béky2fcf4fa2018-04-06 20:06:0116770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0616771 HttpNetworkTransaction trans(LOW, session.get());
16772 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0116773 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0616774
16775 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0116776 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0616778
Bence Béky2fcf4fa2018-04-06 20:06:0116779 const HttpStreamRequest* stream_request = trans.stream_request_.get();
16780 ASSERT_TRUE(stream_request);
16781 EXPECT_EQ(&websocket_handshake_stream_create_helper,
16782 stream_request->websocket_handshake_stream_create_helper());
16783
16784 rv = callback.WaitForResult();
16785 EXPECT_THAT(rv, IsOk());
16786
16787 EXPECT_TRUE(data.AllReadDataConsumed());
16788 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0616789 }
16790}
16791
Adam Rice425cf122015-01-19 06:18:2416792// Verify that proxy headers are not sent to the destination server when
16793// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116794TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416795 HttpRequestInfo request;
16796 request.method = "GET";
bncce36dca22015-04-21 22:11:2316797 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016798 request.traffic_annotation =
16799 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416800 AddWebSocketHeaders(&request.extra_headers);
16801
16802 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916803 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916804 ProxyResolutionService::CreateFixedFromPacResult(
16805 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416806
danakj1fd259a02016-04-16 03:17:0916807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416808
16809 // Since a proxy is configured, try to establish a tunnel.
16810 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716811 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16812 "Host: www.example.org:443\r\n"
16813 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416814
16815 // After calling trans->RestartWithAuth(), this is the request we should
16816 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716817 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16818 "Host: www.example.org:443\r\n"
16819 "Proxy-Connection: keep-alive\r\n"
16820 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416821
rsleevidb16bb02015-11-12 23:47:1716822 MockWrite("GET / HTTP/1.1\r\n"
16823 "Host: www.example.org\r\n"
16824 "Connection: Upgrade\r\n"
16825 "Upgrade: websocket\r\n"
16826 "Origin: http://www.example.org\r\n"
16827 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1516828 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16829 "Sec-WebSocket-Extensions: permessage-deflate; "
16830 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416831
16832 // The proxy responds to the connect with a 407, using a persistent
16833 // connection.
16834 MockRead data_reads[] = {
16835 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1516836 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
16837 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
16838 "Content-Length: 0\r\n"
16839 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416840
16841 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16842
Bence Béky8d1c6052018-02-07 12:48:1516843 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16844 "Upgrade: websocket\r\n"
16845 "Connection: Upgrade\r\n"
16846 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416847
Ryan Sleevib8d7ea02018-05-07 20:01:0116848 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2416849 session_deps_.socket_factory->AddSocketDataProvider(&data);
16850 SSLSocketDataProvider ssl(ASYNC, OK);
16851 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16852
Bence Béky8d1c6052018-02-07 12:48:1516853 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
16854
bnc87dcefc2017-05-25 12:47:5816855 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916856 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416857 trans->SetWebSocketHandshakeStreamCreateHelper(
16858 &websocket_stream_create_helper);
16859
16860 {
16861 TestCompletionCallback callback;
16862
tfarina42834112016-09-22 13:38:2016863 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416865
16866 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116867 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416868 }
16869
16870 const HttpResponseInfo* response = trans->GetResponseInfo();
16871 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216872 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416873 EXPECT_EQ(407, response->headers->response_code());
16874
16875 {
16876 TestCompletionCallback callback;
16877
16878 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16879 callback.callback());
robpercival214763f2016-07-01 23:27:0116880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416881
16882 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116883 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416884 }
16885
16886 response = trans->GetResponseInfo();
16887 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216888 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416889
16890 EXPECT_EQ(101, response->headers->response_code());
16891
16892 trans.reset();
16893 session->CloseAllConnections();
16894}
16895
16896// Verify that proxy headers are not sent to the destination server when
16897// establishing a tunnel for an insecure WebSocket connection.
16898// This requires the authentication info to be injected into the auth cache
16899// due to crbug.com/395064
16900// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116901TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416902 HttpRequestInfo request;
16903 request.method = "GET";
bncce36dca22015-04-21 22:11:2316904 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016905 request.traffic_annotation =
16906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416907 AddWebSocketHeaders(&request.extra_headers);
16908
16909 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916910 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916911 ProxyResolutionService::CreateFixedFromPacResult(
16912 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416913
danakj1fd259a02016-04-16 03:17:0916914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416915
16916 MockWrite data_writes[] = {
16917 // Try to establish a tunnel for the WebSocket connection, with
16918 // credentials. Because WebSockets have a separate set of socket pools,
16919 // they cannot and will not use the same TCP/IP connection as the
16920 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1516921 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
16922 "Host: www.example.org:80\r\n"
16923 "Proxy-Connection: keep-alive\r\n"
16924 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416925
Bence Béky8d1c6052018-02-07 12:48:1516926 MockWrite("GET / HTTP/1.1\r\n"
16927 "Host: www.example.org\r\n"
16928 "Connection: Upgrade\r\n"
16929 "Upgrade: websocket\r\n"
16930 "Origin: http://www.example.org\r\n"
16931 "Sec-WebSocket-Version: 13\r\n"
16932 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16933 "Sec-WebSocket-Extensions: permessage-deflate; "
16934 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416935
16936 MockRead data_reads[] = {
16937 // HTTP CONNECT with credentials.
16938 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16939
16940 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1516941 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16942 "Upgrade: websocket\r\n"
16943 "Connection: Upgrade\r\n"
16944 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416945
Ryan Sleevib8d7ea02018-05-07 20:01:0116946 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2416947 session_deps_.socket_factory->AddSocketDataProvider(&data);
16948
16949 session->http_auth_cache()->Add(
16950 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16951 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16952
Bence Béky8d1c6052018-02-07 12:48:1516953 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
16954
bnc87dcefc2017-05-25 12:47:5816955 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916956 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416957 trans->SetWebSocketHandshakeStreamCreateHelper(
16958 &websocket_stream_create_helper);
16959
16960 TestCompletionCallback callback;
16961
tfarina42834112016-09-22 13:38:2016962 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416964
16965 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116966 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416967
16968 const HttpResponseInfo* response = trans->GetResponseInfo();
16969 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216970 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416971
16972 EXPECT_EQ(101, response->headers->response_code());
16973
16974 trans.reset();
16975 session->CloseAllConnections();
16976}
16977
Bence Békydca6bd92018-01-30 13:43:0616978#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
16979
bncd16676a2016-07-20 16:23:0116980TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916981 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216982 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916983 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216984 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216985
16986 HttpRequestInfo request;
16987 request.method = "POST";
16988 request.url = GURL("http://www.foo.com/");
16989 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016990 request.traffic_annotation =
16991 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2216992
danakj1fd259a02016-04-16 03:17:0916993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216995 MockWrite data_writes[] = {
16996 MockWrite("POST / HTTP/1.1\r\n"
16997 "Host: www.foo.com\r\n"
16998 "Connection: keep-alive\r\n"
16999 "Content-Length: 3\r\n\r\n"),
17000 MockWrite("foo"),
17001 };
17002
17003 MockRead data_reads[] = {
17004 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17005 MockRead(SYNCHRONOUS, OK),
17006 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117007 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217008 session_deps_.socket_factory->AddSocketDataProvider(&data);
17009
17010 TestCompletionCallback callback;
17011
17012 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017013 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117014 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217015
17016 std::string response_data;
bnc691fda62016-08-12 00:43:1617017 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217018
Ryan Sleevib8d7ea02018-05-07 20:01:0117019 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17020 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217021}
17022
bncd16676a2016-07-20 16:23:0117023TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917024 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217025 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917026 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217027 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217028
17029 HttpRequestInfo request;
17030 request.method = "POST";
17031 request.url = GURL("http://www.foo.com/");
17032 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017033 request.traffic_annotation =
17034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217035
danakj1fd259a02016-04-16 03:17:0917036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217038 MockWrite data_writes[] = {
17039 MockWrite("POST / HTTP/1.1\r\n"
17040 "Host: www.foo.com\r\n"
17041 "Connection: keep-alive\r\n"
17042 "Content-Length: 3\r\n\r\n"),
17043 MockWrite("foo"),
17044 };
17045
17046 MockRead data_reads[] = {
17047 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17048 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17049 MockRead(SYNCHRONOUS, OK),
17050 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117051 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217052 session_deps_.socket_factory->AddSocketDataProvider(&data);
17053
17054 TestCompletionCallback callback;
17055
17056 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017057 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117058 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217059
17060 std::string response_data;
bnc691fda62016-08-12 00:43:1617061 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217062
Ryan Sleevib8d7ea02018-05-07 20:01:0117063 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17064 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217065}
17066
bncd16676a2016-07-20 16:23:0117067TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217068 ChunkedUploadDataStream upload_data_stream(0);
17069
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 // Send headers successfully, but get an error while sending the body.
17080 MockWrite data_writes[] = {
17081 MockWrite("POST / HTTP/1.1\r\n"
17082 "Host: www.foo.com\r\n"
17083 "Connection: keep-alive\r\n"
17084 "Transfer-Encoding: chunked\r\n\r\n"),
17085 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17086 };
17087
17088 MockRead data_reads[] = {
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()));
sclittlefb249892015-09-10 21:33:2217099
17100 base::RunLoop().RunUntilIdle();
17101 upload_data_stream.AppendData("f", 1, false);
17102
17103 base::RunLoop().RunUntilIdle();
17104 upload_data_stream.AppendData("oo", 2, true);
17105
robpercival214763f2016-07-01 23:27:0117106 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217107
17108 std::string response_data;
bnc691fda62016-08-12 00:43:1617109 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217110
Ryan Sleevib8d7ea02018-05-07 20:01:0117111 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17112 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217113}
17114
nharperb7441ef2016-01-25 23:54:1417115#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117116TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417117 const std::string https_url = "https://www.example.com";
17118 HttpRequestInfo request;
17119 request.url = GURL(https_url);
17120 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:1017121 request.traffic_annotation =
17122 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417123
17124 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917125 ssl.ssl_info.token_binding_negotiated = true;
17126 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617127 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417128 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17129
bnc42331402016-07-25 13:36:1517130 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117131 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17132 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417133 MockRead(ASYNC, ERR_IO_PENDING)};
Ryan Sleevib8d7ea02018-05-07 20:01:0117134 StaticSocketDataProvider data(reads, base::span<MockWrite>());
nharperb7441ef2016-01-25 23:54:1417135 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817136 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917137 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917138 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417139
17140 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17141 TestCompletionCallback callback;
17142 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017143 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017144
17145 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417146
17147 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17148 HttpRequestHeaders headers;
17149 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17150 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17151}
17152#endif // !defined(OS_IOS)
17153
eustasc7d27da2017-04-06 10:33:2017154void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17155 const std::string& accept_encoding,
17156 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317157 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017158 bool should_match) {
17159 HttpRequestInfo request;
17160 request.method = "GET";
17161 request.url = GURL("http://www.foo.com/");
17162 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17163 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1017164 request.traffic_annotation =
17165 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017166
17167 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17168 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17169 // Send headers successfully, but get an error while sending the body.
17170 MockWrite data_writes[] = {
17171 MockWrite("GET / HTTP/1.1\r\n"
17172 "Host: www.foo.com\r\n"
17173 "Connection: keep-alive\r\n"
17174 "Accept-Encoding: "),
17175 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17176 };
17177
sky50576f32017-05-01 19:28:0317178 std::string response_code = "200 OK";
17179 std::string extra;
17180 if (!location.empty()) {
17181 response_code = "301 Redirect\r\nLocation: ";
17182 response_code.append(location);
17183 }
17184
eustasc7d27da2017-04-06 10:33:2017185 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317186 MockRead("HTTP/1.0 "),
17187 MockRead(response_code.data()),
17188 MockRead("\r\nContent-Encoding: "),
17189 MockRead(content_encoding.data()),
17190 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017191 MockRead(SYNCHRONOUS, OK),
17192 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117193 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2017194 session_deps->socket_factory->AddSocketDataProvider(&data);
17195
17196 TestCompletionCallback callback;
17197
17198 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17199 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17200
17201 rv = callback.WaitForResult();
17202 if (should_match) {
17203 EXPECT_THAT(rv, IsOk());
17204 } else {
17205 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17206 }
17207}
17208
17209TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317210 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017211}
17212
17213TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317214 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17215 true);
eustasc7d27da2017-04-06 10:33:2017216}
17217
17218TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17219 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317220 "", false);
17221}
17222
17223TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17224 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17225 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017226}
17227
xunjieli96f2a402017-06-05 17:24:2717228TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17229 ProxyConfig proxy_config;
17230 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17231 proxy_config.set_pac_mandatory(true);
17232 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917233 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917234 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17235 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0417236 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717237
17238 HttpRequestInfo request;
17239 request.method = "GET";
17240 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017241 request.traffic_annotation =
17242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717243
17244 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17245 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17246
17247 TestCompletionCallback callback;
17248
17249 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17251 EXPECT_THAT(callback.WaitForResult(),
17252 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17253}
17254
17255TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17256 ProxyConfig proxy_config;
17257 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17258 proxy_config.set_pac_mandatory(true);
17259 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17260 new MockAsyncProxyResolverFactory(false);
17261 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917262 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917263 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17264 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5917265 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717266 HttpRequestInfo request;
17267 request.method = "GET";
17268 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017269 request.traffic_annotation =
17270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717271
17272 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17273 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17274
17275 TestCompletionCallback callback;
17276 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17278
17279 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17280 ERR_FAILED, &resolver);
17281 EXPECT_THAT(callback.WaitForResult(),
17282 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17283}
17284
17285TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917286 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917287 ProxyResolutionService::CreateFixedFromPacResult(
17288 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717289 session_deps_.enable_quic = false;
17290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17291
17292 HttpRequestInfo request;
17293 request.method = "GET";
17294 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017295 request.traffic_annotation =
17296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717297
17298 TestCompletionCallback callback;
17299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17300 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17302
17303 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17304}
17305
[email protected]89ceba9a2009-03-21 03:46:0617306} // namespace net