blob: f86255e5f518557cb4760b60c31983e5c49d257a [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"
89#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1490#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0392#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5793#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5494#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1195#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0196#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1097#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:4398#include "net/test/test_data_directory.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
[email protected]5a60c8b2011-10-19 20:14:29351 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
352 size_t data_count) {
[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 Halavatib5e433e2018-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
[email protected]5a60c8b2011-10-19 20:14:29366 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07367 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[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
[email protected]5a60c8b2011-10-19 20:14:29442 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
443 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22444 MockWrite data_writes[] = {
445 MockWrite("GET / HTTP/1.1\r\n"
446 "Host: www.example.org\r\n"
447 "Connection: keep-alive\r\n\r\n"),
448 };
[email protected]5a60c8b2011-10-19 20:14:29449
sclittlefb249892015-09-10 21:33:22450 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
451 arraysize(data_writes));
452 StaticSocketDataProvider* data[] = {&reads};
453 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
454
455 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
456 out.total_sent_bytes);
457 return out;
[email protected]b8015c42013-12-24 15:18:19458 }
459
bnc032658ba2016-09-26 18:17:15460 void AddSSLSocketData() {
461 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49462 ssl_.ssl_info.cert =
463 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
464 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
466 }
467
[email protected]ff007e162009-05-23 09:13:15468 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
469 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52470
[email protected]ff007e162009-05-23 09:13:15471 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07472
[email protected]bb88e1d32013-05-03 23:11:07473 void CheckErrorIsPassedBack(int error, IoMode mode);
474
[email protected]4bd46222013-05-14 19:32:23475 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07476 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15477 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03478
479 // Original socket limits. Some tests set these. Safest to always restore
480 // them once each test has been run.
481 int old_max_group_sockets_;
482 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15483};
[email protected]231d5a32008-09-13 00:45:27484
[email protected]448d4ca52012-03-04 04:12:23485namespace {
486
ryansturm49a8cb12016-06-15 16:51:09487class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27488 public:
ryansturm49a8cb12016-06-15 16:51:09489 BeforeHeadersSentHandler()
490 : observed_before_headers_sent_with_proxy_(false),
491 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27492
ryansturm49a8cb12016-06-15 16:51:09493 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
494 HttpRequestHeaders* request_headers) {
495 observed_before_headers_sent_ = true;
496 if (!proxy_info.is_http() && !proxy_info.is_https() &&
497 !proxy_info.is_quic()) {
498 return;
499 }
500 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27501 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
502 }
503
ryansturm49a8cb12016-06-15 16:51:09504 bool observed_before_headers_sent_with_proxy() const {
505 return observed_before_headers_sent_with_proxy_;
506 }
507
508 bool observed_before_headers_sent() const {
509 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27510 }
511
512 std::string observed_proxy_server_uri() const {
513 return observed_proxy_server_uri_;
514 }
515
516 private:
ryansturm49a8cb12016-06-15 16:51:09517 bool observed_before_headers_sent_with_proxy_;
518 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27519 std::string observed_proxy_server_uri_;
520
ryansturm49a8cb12016-06-15 16:51:09521 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27522};
523
[email protected]15a5ccf82008-10-23 19:57:43524// Fill |str| with a long header list that consumes >= |size| bytes.
525void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51526 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19527 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
528 const int sizeof_row = strlen(row);
529 const int num_rows = static_cast<int>(
530 ceil(static_cast<float>(size) / sizeof_row));
531 const int sizeof_data = num_rows * sizeof_row;
532 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43533 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51534
[email protected]4ddaf2502008-10-23 18:26:19535 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43536 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19537}
538
thakis84dff942015-07-28 20:47:38539#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09540uint64_t MockGetMSTime() {
541 // Tue, 23 May 2017 20:13:07 +0000
542 return 131400439870000000;
543}
544
[email protected]385a4672009-03-11 22:21:29545// Alternative functions that eliminate randomness and dependency on the local
546// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37547void MockGenerateRandom(uint8_t* output, size_t n) {
548 // This is set to 0xaa because the client challenge for testing in
549 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
550 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29551}
552
[email protected]fe2bc6a2009-03-23 16:52:20553std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37554 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29555}
thakis84dff942015-07-28 20:47:38556#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29557
[email protected]e60e47a2010-07-14 03:37:18558template<typename ParentPool>
559class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31560 public:
[email protected]9e1bdd32011-02-03 21:48:34561 CaptureGroupNameSocketPool(HostResolver* host_resolver,
562 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18563
[email protected]d80a4322009-08-14 07:07:49564 const std::string last_group_name_received() const {
565 return last_group_name_;
566 }
567
Tarun Bansal162eabe52018-01-20 01:16:39568 bool socket_requested() const { return socket_requested_; }
569
dmichaeld6e570d2014-12-18 22:30:57570 int RequestSocket(const std::string& group_name,
571 const void* socket_params,
572 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54573 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15574 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57575 ClientSocketHandle* handle,
576 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20577 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31578 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39579 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31580 return ERR_IO_PENDING;
581 }
dmichaeld6e570d2014-12-18 22:30:57582 void CancelRequest(const std::string& group_name,
583 ClientSocketHandle* handle) override {}
584 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09585 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57586 int id) override {}
587 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23588 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57589 int IdleSocketCount() const override { return 0; }
590 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31591 return 0;
592 }
dmichaeld6e570d2014-12-18 22:30:57593 LoadState GetLoadState(const std::string& group_name,
594 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31595 return LOAD_STATE_IDLE;
596 }
dmichaeld6e570d2014-12-18 22:30:57597 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26598 return base::TimeDelta();
599 }
[email protected]d80a4322009-08-14 07:07:49600
601 private:
[email protected]04e5be32009-06-26 20:00:31602 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39603 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31604};
605
[email protected]ab739042011-04-07 15:22:28606typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
607CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13608typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
609CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06610typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11611CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18612typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
613CaptureGroupNameSSLSocketPool;
614
rkaplowd90695c2015-03-25 22:12:41615template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18616CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34617 HostResolver* host_resolver,
618 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21619 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18620
hashimoto0d3e4fb2015-01-09 05:02:50621template <>
[email protected]2df19bb2010-08-25 20:13:46622CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21623 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34624 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09625 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46626
[email protected]007b3f82013-04-09 08:46:45627template <>
[email protected]e60e47a2010-07-14 03:37:18628CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21629 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34630 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45631 : SSLClientSocketPool(0,
632 0,
[email protected]007b3f82013-04-09 08:46:45633 cert_verifier,
634 NULL,
635 NULL,
[email protected]284303b62013-11-28 15:11:54636 NULL,
eranm6571b2b2014-12-03 15:53:23637 NULL,
[email protected]007b3f82013-04-09 08:46:45638 std::string(),
639 NULL,
640 NULL,
641 NULL,
642 NULL,
643 NULL,
[email protected]8e458552014-08-05 00:02:15644 NULL) {
645}
[email protected]2227c692010-05-04 15:36:11646
[email protected]231d5a32008-09-13 00:45:27647//-----------------------------------------------------------------------------
648
[email protected]79cb5c12011-09-12 13:12:04649// Helper functions for validating that AuthChallengeInfo's are correctly
650// configured for common cases.
651bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
652 if (!auth_challenge)
653 return false;
654 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43655 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04656 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19657 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04658 return true;
659}
660
661bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
662 if (!auth_challenge)
663 return false;
664 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43665 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
666 EXPECT_EQ("MyRealm1", auth_challenge->realm);
667 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
668 return true;
669}
670
671bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
672 if (!auth_challenge)
673 return false;
674 EXPECT_TRUE(auth_challenge->is_proxy);
675 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04676 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19677 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04678 return true;
679}
680
681bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
682 if (!auth_challenge)
683 return false;
684 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43685 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04686 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19687 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04688 return true;
689}
690
thakis84dff942015-07-28 20:47:38691#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04692bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
693 if (!auth_challenge)
694 return false;
695 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55696 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04697 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19698 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04699 return true;
700}
David Benjamin5cb91132018-04-06 05:54:49701
702bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
703 if (!auth_challenge)
704 return false;
705 EXPECT_TRUE(auth_challenge->is_proxy);
706 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
707 EXPECT_EQ(std::string(), auth_challenge->realm);
708 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
709 return true;
710}
thakis84dff942015-07-28 20:47:38711#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04712
[email protected]448d4ca52012-03-04 04:12:23713} // namespace
714
bncd16676a2016-07-20 16:23:01715TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27718}
719
bncd16676a2016-07-20 16:23:01720TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27721 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35722 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
723 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06724 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27725 };
[email protected]31a2bfe2010-02-09 08:03:39726 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
727 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01728 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27729 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
730 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22731 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
732 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47733 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59734
735 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27736}
737
738// Response with no status line.
bncd16676a2016-07-20 16:23:01739TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27740 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35741 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06742 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27743 };
[email protected]31a2bfe2010-02-09 08:03:39744 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
745 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41746 EXPECT_THAT(out.rv, IsOk());
747 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
748 EXPECT_EQ("hello world", out.response_data);
749 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
750 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27751}
752
mmenkea7da6da2016-09-01 21:56:52753// Response with no status line, and a weird port. Should fail by default.
754TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
755 MockRead data_reads[] = {
756 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
757 };
758
759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
760 session_deps_.socket_factory->AddSocketDataProvider(&data);
761
762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
763
krasinc06a72a2016-12-21 03:42:46764 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58765 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19766 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52767
mmenkea7da6da2016-09-01 21:56:52768 request.method = "GET";
769 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10770 request.traffic_annotation =
771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
772
mmenkea7da6da2016-09-01 21:56:52773 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20774 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52775 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
776}
777
Shivani Sharmafdcaefd2017-11-02 00:12:26778// Tests that request info can be destroyed after the headers phase is complete.
779TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
781 auto trans =
782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
783
784 MockRead data_reads[] = {
785 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
786 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
787 };
788 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
789 session_deps_.socket_factory->AddSocketDataProvider(&data);
790
791 TestCompletionCallback callback;
792
793 {
794 auto request = std::make_unique<HttpRequestInfo>();
795 request->method = "GET";
796 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10797 request->traffic_annotation =
798 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26799
800 int rv =
801 trans->Start(request.get(), callback.callback(), NetLogWithSource());
802
803 EXPECT_THAT(callback.GetResult(rv), IsOk());
804 } // Let request info be destroyed.
805
806 trans.reset();
807}
808
mmenkea7da6da2016-09-01 21:56:52809// Response with no status line, and a weird port. Option to allow weird ports
810// enabled.
811TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
812 MockRead data_reads[] = {
813 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
814 };
815
816 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
817 session_deps_.socket_factory->AddSocketDataProvider(&data);
818 session_deps_.http_09_on_non_default_ports_enabled = true;
819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
820
krasinc06a72a2016-12-21 03:42:46821 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58822 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19823 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52824
mmenkea7da6da2016-09-01 21:56:52825 request.method = "GET";
826 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10827 request.traffic_annotation =
828 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
829
mmenkea7da6da2016-09-01 21:56:52830 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20831 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52832 EXPECT_THAT(callback.GetResult(rv), IsOk());
833
834 const HttpResponseInfo* info = trans->GetResponseInfo();
835 ASSERT_TRUE(info->headers);
836 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
837
838 // Don't bother to read the body - that's verified elsewhere, important thing
839 // is that the option to allow HTTP/0.9 on non-default ports is respected.
840}
841
[email protected]231d5a32008-09-13 00:45:27842// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01843TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27844 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35845 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06846 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27847 };
[email protected]31a2bfe2010-02-09 08:03:39848 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
849 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01850 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27851 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
852 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22853 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
854 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27855}
856
857// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01858TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27859 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35860 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06861 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27862 };
[email protected]31a2bfe2010-02-09 08:03:39863 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
864 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01865 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27866 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
867 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22868 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
869 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27870}
871
872// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01873TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27874 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35875 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06876 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27877 };
[email protected]31a2bfe2010-02-09 08:03:39878 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
879 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41880 EXPECT_THAT(out.rv, IsOk());
881 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
882 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
883 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
884 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27885}
886
887// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01888TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27889 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35890 MockRead("\n"),
891 MockRead("\n"),
892 MockRead("Q"),
893 MockRead("J"),
894 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06895 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27896 };
[email protected]31a2bfe2010-02-09 08:03:39897 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
898 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01899 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27900 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
901 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22902 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
903 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27904}
905
906// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01907TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27908 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35909 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06910 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27911 };
[email protected]31a2bfe2010-02-09 08:03:39912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41914 EXPECT_THAT(out.rv, IsOk());
915 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
916 EXPECT_EQ("HTT", out.response_data);
917 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
918 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52919}
920
[email protected]f9d44aa2008-09-23 23:57:17921// Simulate a 204 response, lacking a Content-Length header, sent over a
922// persistent connection. The response should still terminate since a 204
923// cannot have a response body.
bncd16676a2016-07-20 16:23:01924TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19925 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17926 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35927 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19928 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06929 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17930 };
[email protected]31a2bfe2010-02-09 08:03:39931 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
932 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01933 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17934 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
935 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22936 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
937 int64_t response_size = reads_size - strlen(junk);
938 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17939}
940
[email protected]0877e3d2009-10-17 22:29:57941// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01942TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19943 std::string final_chunk = "0\r\n\r\n";
944 std::string extra_data = "HTTP/1.1 200 OK\r\n";
945 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57946 MockRead data_reads[] = {
947 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
948 MockRead("5\r\nHello\r\n"),
949 MockRead("1\r\n"),
950 MockRead(" \r\n"),
951 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19952 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06953 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57954 };
[email protected]31a2bfe2010-02-09 08:03:39955 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
956 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01957 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:57958 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
959 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22960 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
961 int64_t response_size = reads_size - extra_data.size();
962 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57963}
964
[email protected]9fe44f52010-09-23 18:36:00965// Next tests deal with http://crbug.com/56344.
966
bncd16676a2016-07-20 16:23:01967TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00968 MultipleContentLengthHeadersNoTransferEncoding) {
969 MockRead data_reads[] = {
970 MockRead("HTTP/1.1 200 OK\r\n"),
971 MockRead("Content-Length: 10\r\n"),
972 MockRead("Content-Length: 5\r\n\r\n"),
973 };
974 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
975 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01976 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:00977}
978
bncd16676a2016-07-20 16:23:01979TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04980 DuplicateContentLengthHeadersNoTransferEncoding) {
981 MockRead data_reads[] = {
982 MockRead("HTTP/1.1 200 OK\r\n"),
983 MockRead("Content-Length: 5\r\n"),
984 MockRead("Content-Length: 5\r\n\r\n"),
985 MockRead("Hello"),
986 };
987 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
988 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01989 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04990 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
991 EXPECT_EQ("Hello", out.response_data);
992}
993
bncd16676a2016-07-20 16:23:01994TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04995 ComplexContentLengthHeadersNoTransferEncoding) {
996 // More than 2 dupes.
997 {
998 MockRead data_reads[] = {
999 MockRead("HTTP/1.1 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 };
1005 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1006 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011007 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041008 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1009 EXPECT_EQ("Hello", out.response_data);
1010 }
1011 // HTTP/1.0
1012 {
1013 MockRead data_reads[] = {
1014 MockRead("HTTP/1.0 200 OK\r\n"),
1015 MockRead("Content-Length: 5\r\n"),
1016 MockRead("Content-Length: 5\r\n"),
1017 MockRead("Content-Length: 5\r\n\r\n"),
1018 MockRead("Hello"),
1019 };
1020 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1021 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011022 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041023 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1024 EXPECT_EQ("Hello", out.response_data);
1025 }
1026 // 2 dupes and one mismatched.
1027 {
1028 MockRead data_reads[] = {
1029 MockRead("HTTP/1.1 200 OK\r\n"),
1030 MockRead("Content-Length: 10\r\n"),
1031 MockRead("Content-Length: 10\r\n"),
1032 MockRead("Content-Length: 5\r\n\r\n"),
1033 };
1034 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1035 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011036 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041037 }
1038}
1039
bncd16676a2016-07-20 16:23:011040TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001041 MultipleContentLengthHeadersTransferEncoding) {
1042 MockRead data_reads[] = {
1043 MockRead("HTTP/1.1 200 OK\r\n"),
1044 MockRead("Content-Length: 666\r\n"),
1045 MockRead("Content-Length: 1337\r\n"),
1046 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1047 MockRead("5\r\nHello\r\n"),
1048 MockRead("1\r\n"),
1049 MockRead(" \r\n"),
1050 MockRead("5\r\nworld\r\n"),
1051 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061052 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001053 };
1054 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1055 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011056 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001057 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1058 EXPECT_EQ("Hello world", out.response_data);
1059}
1060
[email protected]1628fe92011-10-04 23:04:551061// Next tests deal with http://crbug.com/98895.
1062
1063// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011064TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551065 MockRead data_reads[] = {
1066 MockRead("HTTP/1.1 200 OK\r\n"),
1067 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1068 MockRead("Content-Length: 5\r\n\r\n"),
1069 MockRead("Hello"),
1070 };
1071 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1072 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011073 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551074 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1075 EXPECT_EQ("Hello", out.response_data);
1076}
1077
[email protected]54a9c6e52012-03-21 20:10:591078// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011079TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551080 MockRead data_reads[] = {
1081 MockRead("HTTP/1.1 200 OK\r\n"),
1082 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1083 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1084 MockRead("Content-Length: 5\r\n\r\n"),
1085 MockRead("Hello"),
1086 };
1087 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1088 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011089 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591090 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1091 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551092}
1093
1094// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011095TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551096 MockRead data_reads[] = {
1097 MockRead("HTTP/1.1 200 OK\r\n"),
1098 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1099 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1100 MockRead("Content-Length: 5\r\n\r\n"),
1101 MockRead("Hello"),
1102 };
1103 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1104 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011105 EXPECT_THAT(out.rv,
1106 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551107}
1108
[email protected]54a9c6e52012-03-21 20:10:591109// Checks that two identical Location headers result in no error.
1110// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011111TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551112 MockRead data_reads[] = {
1113 MockRead("HTTP/1.1 302 Redirect\r\n"),
1114 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591115 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551116 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061117 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551118 };
1119
1120 HttpRequestInfo request;
1121 request.method = "GET";
1122 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101123 request.traffic_annotation =
1124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551125
danakj1fd259a02016-04-16 03:17:091126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551128
1129 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071130 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551131
[email protected]49639fa2011-12-20 23:22:411132 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551133
tfarina42834112016-09-22 13:38:201134 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011135 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551136
robpercival214763f2016-07-01 23:27:011137 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551138
bnc691fda62016-08-12 00:43:161139 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521140 ASSERT_TRUE(response);
1141 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551142 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1143 std::string url;
1144 EXPECT_TRUE(response->headers->IsRedirect(&url));
1145 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471146 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551147}
1148
[email protected]1628fe92011-10-04 23:04:551149// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011150TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551151 MockRead data_reads[] = {
1152 MockRead("HTTP/1.1 302 Redirect\r\n"),
1153 MockRead("Location: http://good.com/\r\n"),
1154 MockRead("Location: http://evil.com/\r\n"),
1155 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061156 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551157 };
1158 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1159 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011160 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551161}
1162
[email protected]ef0faf2e72009-03-05 23:27:231163// Do a request using the HEAD method. Verify that we don't try to read the
1164// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011165TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421166 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231167 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231168 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101169 request.traffic_annotation =
1170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231171
danakj1fd259a02016-04-16 03:17:091172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091174 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161175 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091176 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1177 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271178
[email protected]ef0faf2e72009-03-05 23:27:231179 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131180 MockWrite("HEAD / HTTP/1.1\r\n"
1181 "Host: www.example.org\r\n"
1182 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231183 };
1184 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231185 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1186 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231187
mmenked39192ee2015-12-09 00:57:231188 // No response body because the test stops reading here.
1189 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231190 };
1191
[email protected]31a2bfe2010-02-09 08:03:391192 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1193 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071194 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231195
[email protected]49639fa2011-12-20 23:22:411196 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231197
tfarina42834112016-09-22 13:38:201198 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011199 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231200
1201 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011202 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231203
bnc691fda62016-08-12 00:43:161204 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521205 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231206
1207 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521208 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231209 EXPECT_EQ(1234, response->headers->GetContentLength());
1210 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471211 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091212 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1213 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231214
1215 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101216 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231217 bool has_server_header = response->headers->EnumerateHeader(
1218 &iter, "Server", &server_header);
1219 EXPECT_TRUE(has_server_header);
1220 EXPECT_EQ("Blah", server_header);
1221
1222 // Reading should give EOF right away, since there is no message body
1223 // (despite non-zero content-length).
1224 std::string response_data;
bnc691fda62016-08-12 00:43:161225 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011226 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231227 EXPECT_EQ("", response_data);
1228}
1229
bncd16676a2016-07-20 16:23:011230TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091231 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521232
1233 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351234 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1235 MockRead("hello"),
1236 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1237 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061238 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521239 };
[email protected]31a2bfe2010-02-09 08:03:391240 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071241 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521242
[email protected]0b0bf032010-09-21 18:08:501243 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521244 "hello", "world"
1245 };
1246
1247 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421248 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521249 request.method = "GET";
bncce36dca22015-04-21 22:11:231250 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101251 request.traffic_annotation =
1252 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521253
bnc691fda62016-08-12 00:43:161254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271255
[email protected]49639fa2011-12-20 23:22:411256 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521257
tfarina42834112016-09-22 13:38:201258 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521260
1261 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011262 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521263
bnc691fda62016-08-12 00:43:161264 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521265 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521266
wezca1070932016-05-26 20:30:521267 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251268 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471269 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521270
1271 std::string response_data;
bnc691fda62016-08-12 00:43:161272 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011273 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251274 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521275 }
1276}
1277
bncd16676a2016-07-20 16:23:011278TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091279 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221280 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191281 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221282 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271283
[email protected]1c773ea12009-04-28 19:58:421284 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521285 request.method = "POST";
1286 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271287 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101288 request.traffic_annotation =
1289 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521290
shivanishab9a143952016-09-19 17:23:411291 // Check the upload progress returned before initialization is correct.
1292 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1293 EXPECT_EQ(0u, progress.size());
1294 EXPECT_EQ(0u, progress.position());
1295
danakj1fd259a02016-04-16 03:17:091296 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271298
initial.commit586acc5fe2008-07-26 22:42:521299 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351300 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1301 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1302 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061303 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521304 };
[email protected]31a2bfe2010-02-09 08:03:391305 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071306 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521307
[email protected]49639fa2011-12-20 23:22:411308 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521309
tfarina42834112016-09-22 13:38:201310 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521312
1313 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011314 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521315
bnc691fda62016-08-12 00:43:161316 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521317 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521318
wezca1070932016-05-26 20:30:521319 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251320 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521321
1322 std::string response_data;
bnc691fda62016-08-12 00:43:161323 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011324 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251325 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521326}
1327
[email protected]3a2d3662009-03-27 03:49:141328// This test is almost the same as Ignores100 above, but the response contains
1329// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571330// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011331TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421332 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141333 request.method = "GET";
1334 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101335 request.traffic_annotation =
1336 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141337
danakj1fd259a02016-04-16 03:17:091338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271340
[email protected]3a2d3662009-03-27 03:49:141341 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571342 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1343 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141344 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061345 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141346 };
[email protected]31a2bfe2010-02-09 08:03:391347 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071348 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141349
[email protected]49639fa2011-12-20 23:22:411350 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141351
tfarina42834112016-09-22 13:38:201352 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141354
1355 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011356 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141357
bnc691fda62016-08-12 00:43:161358 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521359 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141360
wezca1070932016-05-26 20:30:521361 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141362 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1363
1364 std::string response_data;
bnc691fda62016-08-12 00:43:161365 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011366 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141367 EXPECT_EQ("hello world", response_data);
1368}
1369
bncd16676a2016-07-20 16:23:011370TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081371 HttpRequestInfo request;
1372 request.method = "POST";
1373 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101374 request.traffic_annotation =
1375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081376
danakj1fd259a02016-04-16 03:17:091377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161378 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081379
1380 MockRead data_reads[] = {
1381 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1382 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381383 };
zmo9528c9f42015-08-04 22:12:081384 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1385 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381386
zmo9528c9f42015-08-04 22:12:081387 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381388
tfarina42834112016-09-22 13:38:201389 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381391
zmo9528c9f42015-08-04 22:12:081392 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011393 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381394
zmo9528c9f42015-08-04 22:12:081395 std::string response_data;
bnc691fda62016-08-12 00:43:161396 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011397 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081398 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381399}
1400
bncd16676a2016-07-20 16:23:011401TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381402 HttpRequestInfo request;
1403 request.method = "POST";
1404 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101405 request.traffic_annotation =
1406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381407
danakj1fd259a02016-04-16 03:17:091408 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161409 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271410
[email protected]ee9410e72010-01-07 01:42:381411 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061412 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381413 };
[email protected]31a2bfe2010-02-09 08:03:391414 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071415 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381416
[email protected]49639fa2011-12-20 23:22:411417 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381418
tfarina42834112016-09-22 13:38:201419 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381421
1422 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011423 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381424}
1425
[email protected]23e482282013-06-14 16:08:021426void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511427 const MockWrite* write_failure,
1428 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421429 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521430 request.method = "GET";
1431 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101432 request.traffic_annotation =
1433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521434
vishal.b62985ca92015-04-17 08:45:511435 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071436 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271438
[email protected]202965992011-12-07 23:04:511439 // Written data for successfully sending both requests.
1440 MockWrite data1_writes[] = {
1441 MockWrite("GET / HTTP/1.1\r\n"
1442 "Host: www.foo.com\r\n"
1443 "Connection: keep-alive\r\n\r\n"),
1444 MockWrite("GET / HTTP/1.1\r\n"
1445 "Host: www.foo.com\r\n"
1446 "Connection: keep-alive\r\n\r\n")
1447 };
1448
1449 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521450 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351451 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1452 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061453 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521454 };
[email protected]202965992011-12-07 23:04:511455
1456 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491457 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511458 data1_writes[1] = *write_failure;
1459 } else {
1460 ASSERT_TRUE(read_failure);
1461 data1_reads[2] = *read_failure;
1462 }
1463
1464 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1465 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071466 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521467
1468 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351469 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1470 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061471 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521472 };
[email protected]31a2bfe2010-02-09 08:03:391473 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071474 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521475
thestig9d3bb0c2015-01-24 00:49:511476 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521477 "hello", "world"
1478 };
1479
mikecironef22f9812016-10-04 03:40:191480 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521481 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411482 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521483
bnc691fda62016-08-12 00:43:161484 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521485
tfarina42834112016-09-22 13:38:201486 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521488
1489 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011490 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521491
[email protected]58e32bb2013-01-21 18:23:251492 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161493 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251494 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1495 if (i == 0) {
1496 first_socket_log_id = load_timing_info.socket_log_id;
1497 } else {
1498 // The second request should be using a new socket.
1499 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1500 }
1501
bnc691fda62016-08-12 00:43:161502 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521503 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521504
wezca1070932016-05-26 20:30:521505 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471506 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251507 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521508
1509 std::string response_data;
bnc691fda62016-08-12 00:43:161510 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011511 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251512 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521513 }
1514}
[email protected]3d2a59b2008-09-26 19:44:251515
[email protected]a34f61ee2014-03-18 20:59:491516void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1517 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101518 const MockRead* read_failure,
1519 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491520 HttpRequestInfo request;
1521 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101522 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101523 request.traffic_annotation =
1524 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491525
vishal.b62985ca92015-04-17 08:45:511526 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491527 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091528 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491529
[email protected]09356c652014-03-25 15:36:101530 SSLSocketDataProvider ssl1(ASYNC, OK);
1531 SSLSocketDataProvider ssl2(ASYNC, OK);
1532 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361533 ssl1.next_proto = kProtoHTTP2;
1534 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101535 }
1536 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1537 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491538
[email protected]09356c652014-03-25 15:36:101539 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411540 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491541 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411542 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151543 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411544 SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191545 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491546
[email protected]09356c652014-03-25 15:36:101547 // HTTP/1.1 versions of the request and response.
1548 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1549 "Host: www.foo.com\r\n"
1550 "Connection: keep-alive\r\n\r\n";
1551 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1552 const char kHttpData[] = "hello";
1553
1554 std::vector<MockRead> data1_reads;
1555 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491556 if (write_failure) {
1557 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101558 data1_writes.push_back(*write_failure);
1559 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491560 } else {
1561 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101562 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411563 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101564 } else {
1565 data1_writes.push_back(MockWrite(kHttpRequest));
1566 }
1567 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491568 }
1569
[email protected]09356c652014-03-25 15:36:101570 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1571 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491572 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1573
[email protected]09356c652014-03-25 15:36:101574 std::vector<MockRead> data2_reads;
1575 std::vector<MockWrite> data2_writes;
1576
1577 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411578 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101579
bncdf80d44fd2016-07-15 20:27:411580 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1581 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101582 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1583 } else {
1584 data2_writes.push_back(
1585 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1586
1587 data2_reads.push_back(
1588 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1589 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1590 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1591 }
rch8e6c6c42015-05-01 14:05:131592 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1593 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491594 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1595
1596 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591597 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491598 // Wait for the preconnect to complete.
1599 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1600 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101601 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491602
1603 // Make the request.
1604 TestCompletionCallback callback;
1605
bnc691fda62016-08-12 00:43:161606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491607
tfarina42834112016-09-22 13:38:201608 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491610
1611 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011612 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491613
1614 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161615 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101616 TestLoadTimingNotReused(
1617 load_timing_info,
1618 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491619
bnc691fda62016-08-12 00:43:161620 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521621 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491622
wezca1070932016-05-26 20:30:521623 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021624 if (response->was_fetched_via_spdy) {
1625 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1626 } else {
1627 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1628 }
[email protected]a34f61ee2014-03-18 20:59:491629
1630 std::string response_data;
bnc691fda62016-08-12 00:43:161631 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011632 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101633 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491634}
1635
Biljith Jayan45a41722017-08-16 18:43:141636// Test that we do not retry indefinitely when a server sends an error like
1637// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1638// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1639TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1640 HttpRequestInfo request;
1641 request.method = "GET";
1642 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101643 request.traffic_annotation =
1644 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141645
1646 // Check whether we give up after the third try.
1647
1648 // Construct an HTTP2 request and a "Go away" response.
1649 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1650 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291651 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141652 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1653 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1654
1655 // Three go away responses.
1656 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1657 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1658 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1659
1660 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1661 AddSSLSocketData();
1662 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1663 AddSSLSocketData();
1664 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1665 AddSSLSocketData();
1666
1667 TestCompletionCallback callback;
1668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1670
1671 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1673
1674 rv = callback.WaitForResult();
1675 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1676}
1677
1678TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1679 HttpRequestInfo request;
1680 request.method = "GET";
1681 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101682 request.traffic_annotation =
1683 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141684
1685 // Check whether we try atleast thrice before giving up.
1686
1687 // Construct an HTTP2 request and a "Go away" response.
1688 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1689 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291690 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141691 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1692 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1693
1694 // Construct a non error HTTP2 response.
1695 SpdySerializedFrame spdy_response_no_error(
1696 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1697 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1698 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1699 CreateMockRead(spdy_data, 2)};
1700
1701 // Two error responses.
1702 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1703 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1704 // Followed by a success response.
1705 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1706
1707 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1708 AddSSLSocketData();
1709 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1710 AddSSLSocketData();
1711 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1712 AddSSLSocketData();
1713
1714 TestCompletionCallback callback;
1715 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1716 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1717
1718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1720
1721 rv = callback.WaitForResult();
1722 EXPECT_THAT(rv, IsOk());
1723}
1724
bncd16676a2016-07-20 16:23:011725TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061726 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511727 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1728}
1729
bncd16676a2016-07-20 16:23:011730TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061731 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511732 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251733}
1734
bncd16676a2016-07-20 16:23:011735TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061736 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511737 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251738}
1739
[email protected]d58ceea82014-06-04 10:55:541740// Make sure that on a 408 response (Request Timeout), the request is retried,
1741// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011742TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541743 MockRead read_failure(SYNCHRONOUS,
1744 "HTTP/1.1 408 Request Timeout\r\n"
1745 "Connection: Keep-Alive\r\n"
1746 "Content-Length: 6\r\n\r\n"
1747 "Pickle");
1748 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1749}
1750
bncd16676a2016-07-20 16:23:011751TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491752 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101753 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491754}
1755
bncd16676a2016-07-20 16:23:011756TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491757 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101758 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491759}
1760
bncd16676a2016-07-20 16:23:011761TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491762 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101763 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1764}
1765
bncd16676a2016-07-20 16:23:011766TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101767 MockRead read_failure(ASYNC, OK); // EOF
1768 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1769}
1770
[email protected]d58ceea82014-06-04 10:55:541771// Make sure that on a 408 response (Request Timeout), the request is retried,
1772// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011773TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541774 MockRead read_failure(SYNCHRONOUS,
1775 "HTTP/1.1 408 Request Timeout\r\n"
1776 "Connection: Keep-Alive\r\n"
1777 "Content-Length: 6\r\n\r\n"
1778 "Pickle");
1779 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1780 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1781}
1782
bncd16676a2016-07-20 16:23:011783TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101784 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1785 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1786}
1787
bncd16676a2016-07-20 16:23:011788TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101789 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1790 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1791}
1792
bncd16676a2016-07-20 16:23:011793TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101794 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1795 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1796}
1797
bncd16676a2016-07-20 16:23:011798TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101799 MockRead read_failure(ASYNC, OK); // EOF
1800 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491801}
1802
bncd16676a2016-07-20 16:23:011803TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421804 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251805 request.method = "GET";
bncce36dca22015-04-21 22:11:231806 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101807 request.traffic_annotation =
1808 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251809
danakj1fd259a02016-04-16 03:17:091810 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271812
[email protected]3d2a59b2008-09-26 19:44:251813 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061814 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351815 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1816 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061817 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251818 };
[email protected]31a2bfe2010-02-09 08:03:391819 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071820 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251821
[email protected]49639fa2011-12-20 23:22:411822 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251823
tfarina42834112016-09-22 13:38:201824 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251826
1827 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011828 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591829
1830 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161831 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591832 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251833}
1834
1835// What do various browsers do when the server closes a non-keepalive
1836// connection without sending any response header or body?
1837//
1838// IE7: error page
1839// Safari 3.1.2 (Windows): error page
1840// Firefox 3.0.1: blank page
1841// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421842// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1843// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011844TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251845 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061846 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351847 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1848 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061849 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251850 };
[email protected]31a2bfe2010-02-09 08:03:391851 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1852 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011853 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251854}
[email protected]1826a402014-01-08 15:40:481855
[email protected]7a5378b2012-11-04 03:25:171856// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1857// tests. There was a bug causing HttpNetworkTransaction to hang in the
1858// destructor in such situations.
1859// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011860TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171861 HttpRequestInfo request;
1862 request.method = "GET";
bncce36dca22015-04-21 22:11:231863 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101864 request.traffic_annotation =
1865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171866
danakj1fd259a02016-04-16 03:17:091867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581868 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191869 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171870
1871 MockRead data_reads[] = {
1872 MockRead("HTTP/1.0 200 OK\r\n"),
1873 MockRead("Connection: keep-alive\r\n"),
1874 MockRead("Content-Length: 100\r\n\r\n"),
1875 MockRead("hello"),
1876 MockRead(SYNCHRONOUS, 0),
1877 };
1878 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071879 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171880
1881 TestCompletionCallback callback;
1882
tfarina42834112016-09-22 13:38:201883 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171885
1886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011887 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171888
1889 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501890 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171891 if (rv == ERR_IO_PENDING)
1892 rv = callback.WaitForResult();
1893 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501894 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011895 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171896
1897 trans.reset();
fdoray92e35a72016-06-10 15:54:551898 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171899 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1900}
1901
bncd16676a2016-07-20 16:23:011902TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171903 HttpRequestInfo request;
1904 request.method = "GET";
bncce36dca22015-04-21 22:11:231905 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101906 request.traffic_annotation =
1907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171908
danakj1fd259a02016-04-16 03:17:091909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581910 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191911 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171912
1913 MockRead data_reads[] = {
1914 MockRead("HTTP/1.0 200 OK\r\n"),
1915 MockRead("Connection: keep-alive\r\n"),
1916 MockRead("Content-Length: 100\r\n\r\n"),
1917 MockRead(SYNCHRONOUS, 0),
1918 };
1919 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071920 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171921
1922 TestCompletionCallback callback;
1923
tfarina42834112016-09-22 13:38:201924 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171926
1927 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011928 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171929
1930 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501931 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171932 if (rv == ERR_IO_PENDING)
1933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011934 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171935
1936 trans.reset();
fdoray92e35a72016-06-10 15:54:551937 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171938 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1939}
1940
[email protected]0b0bf032010-09-21 18:08:501941// Test that we correctly reuse a keep-alive connection after not explicitly
1942// reading the body.
bncd16676a2016-07-20 16:23:011943TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131944 HttpRequestInfo request;
1945 request.method = "GET";
1946 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101947 request.traffic_annotation =
1948 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:131949
vishal.b62985ca92015-04-17 08:45:511950 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071951 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271953
mmenkecc2298e2015-12-07 18:20:181954 const char* request_data =
1955 "GET / HTTP/1.1\r\n"
1956 "Host: www.foo.com\r\n"
1957 "Connection: keep-alive\r\n\r\n";
1958 MockWrite data_writes[] = {
1959 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1960 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1961 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1962 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1963 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1964 };
1965
[email protected]0b0bf032010-09-21 18:08:501966 // Note that because all these reads happen in the same
1967 // StaticSocketDataProvider, it shows that the same socket is being reused for
1968 // all transactions.
mmenkecc2298e2015-12-07 18:20:181969 MockRead data_reads[] = {
1970 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1971 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1972 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1973 MockRead(ASYNC, 7,
1974 "HTTP/1.1 302 Found\r\n"
1975 "Content-Length: 0\r\n\r\n"),
1976 MockRead(ASYNC, 9,
1977 "HTTP/1.1 302 Found\r\n"
1978 "Content-Length: 5\r\n\r\n"
1979 "hello"),
1980 MockRead(ASYNC, 11,
1981 "HTTP/1.1 301 Moved Permanently\r\n"
1982 "Content-Length: 0\r\n\r\n"),
1983 MockRead(ASYNC, 13,
1984 "HTTP/1.1 301 Moved Permanently\r\n"
1985 "Content-Length: 5\r\n\r\n"
1986 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131987
mmenkecc2298e2015-12-07 18:20:181988 // In the next two rounds, IsConnectedAndIdle returns false, due to
1989 // the set_busy_before_sync_reads(true) call, while the
1990 // HttpNetworkTransaction is being shut down, but the socket is still
1991 // reuseable. See http://crbug.com/544255.
1992 MockRead(ASYNC, 15,
1993 "HTTP/1.1 200 Hunky-Dory\r\n"
1994 "Content-Length: 5\r\n\r\n"),
1995 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131996
mmenkecc2298e2015-12-07 18:20:181997 MockRead(ASYNC, 18,
1998 "HTTP/1.1 200 Hunky-Dory\r\n"
1999 "Content-Length: 5\r\n\r\n"
2000 "he"),
2001 MockRead(SYNCHRONOUS, 19, "llo"),
2002
2003 // The body of the final request is actually read.
2004 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2005 MockRead(ASYNC, 22, "hello"),
2006 };
2007 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2008 arraysize(data_writes));
2009 data.set_busy_before_sync_reads(true);
2010 session_deps_.socket_factory->AddSocketDataProvider(&data);
2011
2012 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502013 std::string response_lines[kNumUnreadBodies];
2014
mikecironef22f9812016-10-04 03:40:192015 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182016 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412017 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132018
Jeremy Roman0579ed62017-08-29 15:56:192019 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582020 session.get());
[email protected]fc31d6a42010-06-24 18:05:132021
tfarina42834112016-09-22 13:38:202022 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012023 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132024
[email protected]58e32bb2013-01-21 18:23:252025 LoadTimingInfo load_timing_info;
2026 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2027 if (i == 0) {
2028 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2029 first_socket_log_id = load_timing_info.socket_log_id;
2030 } else {
2031 TestLoadTimingReused(load_timing_info);
2032 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2033 }
2034
[email protected]fc31d6a42010-06-24 18:05:132035 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182036 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132037
mmenkecc2298e2015-12-07 18:20:182038 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502039 response_lines[i] = response->headers->GetStatusLine();
2040
mmenkecc2298e2015-12-07 18:20:182041 // Delete the transaction without reading the response bodies. Then spin
2042 // the message loop, so the response bodies are drained.
2043 trans.reset();
2044 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132045 }
[email protected]0b0bf032010-09-21 18:08:502046
2047 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182048 "HTTP/1.1 204 No Content",
2049 "HTTP/1.1 205 Reset Content",
2050 "HTTP/1.1 304 Not Modified",
2051 "HTTP/1.1 302 Found",
2052 "HTTP/1.1 302 Found",
2053 "HTTP/1.1 301 Moved Permanently",
2054 "HTTP/1.1 301 Moved Permanently",
2055 "HTTP/1.1 200 Hunky-Dory",
2056 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502057 };
2058
mostynb91e0da982015-01-20 19:17:272059 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2060 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502061
2062 for (int i = 0; i < kNumUnreadBodies; ++i)
2063 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2064
[email protected]49639fa2011-12-20 23:22:412065 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202067 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012068 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162069 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182070 ASSERT_TRUE(response);
2071 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502072 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2073 std::string response_data;
bnc691fda62016-08-12 00:43:162074 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012075 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502076 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132077}
2078
mmenke5f94fda2016-06-02 20:54:132079// Sockets that receive extra data after a response is complete should not be
2080// reused.
bncd16676a2016-07-20 16:23:012081TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132082 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2083 MockWrite data_writes1[] = {
2084 MockWrite("HEAD / HTTP/1.1\r\n"
2085 "Host: www.borked.com\r\n"
2086 "Connection: keep-alive\r\n\r\n"),
2087 };
2088
2089 MockRead data_reads1[] = {
2090 MockRead("HTTP/1.1 200 OK\r\n"
2091 "Connection: keep-alive\r\n"
2092 "Content-Length: 22\r\n\r\n"
2093 "This server is borked."),
2094 };
2095
2096 MockWrite data_writes2[] = {
2097 MockWrite("GET /foo HTTP/1.1\r\n"
2098 "Host: www.borked.com\r\n"
2099 "Connection: keep-alive\r\n\r\n"),
2100 };
2101
2102 MockRead data_reads2[] = {
2103 MockRead("HTTP/1.1 200 OK\r\n"
2104 "Content-Length: 3\r\n\r\n"
2105 "foo"),
2106 };
2107 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2108 data_writes1, arraysize(data_writes1));
2109 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2110 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2111 data_writes2, arraysize(data_writes2));
2112 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2113
2114 TestCompletionCallback callback;
2115 HttpRequestInfo request1;
2116 request1.method = "HEAD";
2117 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102118 request1.traffic_annotation =
2119 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132120
bnc87dcefc2017-05-25 12:47:582121 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192122 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202123 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012124 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132125
2126 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2127 ASSERT_TRUE(response1);
2128 ASSERT_TRUE(response1->headers);
2129 EXPECT_EQ(200, response1->headers->response_code());
2130 EXPECT_TRUE(response1->headers->IsKeepAlive());
2131
2132 std::string response_data1;
robpercival214763f2016-07-01 23:27:012133 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132134 EXPECT_EQ("", response_data1);
2135 // Deleting the transaction attempts to release the socket back into the
2136 // socket pool.
2137 trans1.reset();
2138
2139 HttpRequestInfo request2;
2140 request2.method = "GET";
2141 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102142 request2.traffic_annotation =
2143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132144
bnc87dcefc2017-05-25 12:47:582145 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192146 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202147 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012148 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132149
2150 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2151 ASSERT_TRUE(response2);
2152 ASSERT_TRUE(response2->headers);
2153 EXPECT_EQ(200, response2->headers->response_code());
2154
2155 std::string response_data2;
robpercival214763f2016-07-01 23:27:012156 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132157 EXPECT_EQ("foo", response_data2);
2158}
2159
bncd16676a2016-07-20 16:23:012160TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2162 MockWrite data_writes1[] = {
2163 MockWrite("GET / HTTP/1.1\r\n"
2164 "Host: www.borked.com\r\n"
2165 "Connection: keep-alive\r\n\r\n"),
2166 };
2167
2168 MockRead data_reads1[] = {
2169 MockRead("HTTP/1.1 200 OK\r\n"
2170 "Connection: keep-alive\r\n"
2171 "Content-Length: 22\r\n\r\n"
2172 "This server is borked."
2173 "Bonus data!"),
2174 };
2175
2176 MockWrite data_writes2[] = {
2177 MockWrite("GET /foo HTTP/1.1\r\n"
2178 "Host: www.borked.com\r\n"
2179 "Connection: keep-alive\r\n\r\n"),
2180 };
2181
2182 MockRead data_reads2[] = {
2183 MockRead("HTTP/1.1 200 OK\r\n"
2184 "Content-Length: 3\r\n\r\n"
2185 "foo"),
2186 };
2187 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2188 data_writes1, arraysize(data_writes1));
2189 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2190 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2191 data_writes2, arraysize(data_writes2));
2192 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2193
2194 TestCompletionCallback callback;
2195 HttpRequestInfo request1;
2196 request1.method = "GET";
2197 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102198 request1.traffic_annotation =
2199 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132200
bnc87dcefc2017-05-25 12:47:582201 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192202 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202203 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012204 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132205
2206 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2207 ASSERT_TRUE(response1);
2208 ASSERT_TRUE(response1->headers);
2209 EXPECT_EQ(200, response1->headers->response_code());
2210 EXPECT_TRUE(response1->headers->IsKeepAlive());
2211
2212 std::string response_data1;
robpercival214763f2016-07-01 23:27:012213 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132214 EXPECT_EQ("This server is borked.", response_data1);
2215 // Deleting the transaction attempts to release the socket back into the
2216 // socket pool.
2217 trans1.reset();
2218
2219 HttpRequestInfo request2;
2220 request2.method = "GET";
2221 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102222 request2.traffic_annotation =
2223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132224
bnc87dcefc2017-05-25 12:47:582225 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192226 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202227 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012228 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132229
2230 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2231 ASSERT_TRUE(response2);
2232 ASSERT_TRUE(response2->headers);
2233 EXPECT_EQ(200, response2->headers->response_code());
2234
2235 std::string response_data2;
robpercival214763f2016-07-01 23:27:012236 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132237 EXPECT_EQ("foo", response_data2);
2238}
2239
bncd16676a2016-07-20 16:23:012240TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2242 MockWrite data_writes1[] = {
2243 MockWrite("GET / HTTP/1.1\r\n"
2244 "Host: www.borked.com\r\n"
2245 "Connection: keep-alive\r\n\r\n"),
2246 };
2247
2248 MockRead data_reads1[] = {
2249 MockRead("HTTP/1.1 200 OK\r\n"
2250 "Connection: keep-alive\r\n"
2251 "Transfer-Encoding: chunked\r\n\r\n"),
2252 MockRead("16\r\nThis server is borked.\r\n"),
2253 MockRead("0\r\n\r\nBonus data!"),
2254 };
2255
2256 MockWrite data_writes2[] = {
2257 MockWrite("GET /foo HTTP/1.1\r\n"
2258 "Host: www.borked.com\r\n"
2259 "Connection: keep-alive\r\n\r\n"),
2260 };
2261
2262 MockRead data_reads2[] = {
2263 MockRead("HTTP/1.1 200 OK\r\n"
2264 "Content-Length: 3\r\n\r\n"
2265 "foo"),
2266 };
2267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2268 data_writes1, arraysize(data_writes1));
2269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2270 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2271 data_writes2, arraysize(data_writes2));
2272 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2273
2274 TestCompletionCallback callback;
2275 HttpRequestInfo request1;
2276 request1.method = "GET";
2277 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102278 request1.traffic_annotation =
2279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132280
bnc87dcefc2017-05-25 12:47:582281 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192282 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202283 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012284 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132285
2286 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2287 ASSERT_TRUE(response1);
2288 ASSERT_TRUE(response1->headers);
2289 EXPECT_EQ(200, response1->headers->response_code());
2290 EXPECT_TRUE(response1->headers->IsKeepAlive());
2291
2292 std::string response_data1;
robpercival214763f2016-07-01 23:27:012293 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132294 EXPECT_EQ("This server is borked.", response_data1);
2295 // Deleting the transaction attempts to release the socket back into the
2296 // socket pool.
2297 trans1.reset();
2298
2299 HttpRequestInfo request2;
2300 request2.method = "GET";
2301 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102302 request2.traffic_annotation =
2303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132304
bnc87dcefc2017-05-25 12:47:582305 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192306 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202307 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012308 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132309
2310 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2311 ASSERT_TRUE(response2);
2312 ASSERT_TRUE(response2->headers);
2313 EXPECT_EQ(200, response2->headers->response_code());
2314
2315 std::string response_data2;
robpercival214763f2016-07-01 23:27:012316 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132317 EXPECT_EQ("foo", response_data2);
2318}
2319
2320// This is a little different from the others - it tests the case that the
2321// HttpStreamParser doesn't know if there's extra data on a socket or not when
2322// the HttpNetworkTransaction is torn down, because the response body hasn't
2323// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012324TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2326 MockWrite data_writes1[] = {
2327 MockWrite("GET / HTTP/1.1\r\n"
2328 "Host: www.borked.com\r\n"
2329 "Connection: keep-alive\r\n\r\n"),
2330 };
2331
2332 MockRead data_reads1[] = {
2333 MockRead("HTTP/1.1 200 OK\r\n"
2334 "Connection: keep-alive\r\n"
2335 "Transfer-Encoding: chunked\r\n\r\n"),
2336 MockRead("16\r\nThis server is borked.\r\n"),
2337 MockRead("0\r\n\r\nBonus data!"),
2338 };
2339 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2340 data_writes1, arraysize(data_writes1));
2341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2342
2343 TestCompletionCallback callback;
2344 HttpRequestInfo request1;
2345 request1.method = "GET";
2346 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102347 request1.traffic_annotation =
2348 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132349
bnc87dcefc2017-05-25 12:47:582350 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192351 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582352 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012353 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132354
bnc87dcefc2017-05-25 12:47:582355 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132356 ASSERT_TRUE(response1);
2357 ASSERT_TRUE(response1->headers);
2358 EXPECT_EQ(200, response1->headers->response_code());
2359 EXPECT_TRUE(response1->headers->IsKeepAlive());
2360
2361 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2362 // response body.
bnc87dcefc2017-05-25 12:47:582363 trans.reset();
mmenke5f94fda2016-06-02 20:54:132364
2365 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2366 // socket can't be reused, rather than returning it to the socket pool.
2367 base::RunLoop().RunUntilIdle();
2368
2369 // There should be no idle sockets in the pool.
2370 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2371}
2372
[email protected]038e9a32008-10-08 22:40:162373// Test the request-challenge-retry sequence for basic auth.
2374// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012375TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422376 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162377 request.method = "GET";
bncce36dca22015-04-21 22:11:232378 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102379 request.traffic_annotation =
2380 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162381
vishal.b62985ca92015-04-17 08:45:512382 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072383 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272386
[email protected]f9ee6b52008-11-08 06:46:232387 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232388 MockWrite(
2389 "GET / HTTP/1.1\r\n"
2390 "Host: www.example.org\r\n"
2391 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232392 };
2393
[email protected]038e9a32008-10-08 22:40:162394 MockRead data_reads1[] = {
2395 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2396 // Give a couple authenticate options (only the middle one is actually
2397 // supported).
[email protected]22927ad2009-09-21 19:56:192398 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162399 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2400 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2401 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2402 // Large content-length -- won't matter, as connection will be reset.
2403 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062404 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162405 };
2406
2407 // After calling trans->RestartWithAuth(), this is the request we should
2408 // be issuing -- the final header line contains the credentials.
2409 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232410 MockWrite(
2411 "GET / HTTP/1.1\r\n"
2412 "Host: www.example.org\r\n"
2413 "Connection: keep-alive\r\n"
2414 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162415 };
2416
2417 // Lastly, the server responds with the actual content.
2418 MockRead data_reads2[] = {
2419 MockRead("HTTP/1.0 200 OK\r\n"),
2420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2421 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062422 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162423 };
2424
[email protected]31a2bfe2010-02-09 08:03:392425 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2426 data_writes1, arraysize(data_writes1));
2427 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2428 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072429 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2430 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162431
[email protected]49639fa2011-12-20 23:22:412432 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162433
tfarina42834112016-09-22 13:38:202434 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162436
2437 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012438 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162439
[email protected]58e32bb2013-01-21 18:23:252440 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162441 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252442 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2443
sclittlefb249892015-09-10 21:33:222444 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162445 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222446 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162447 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192448
bnc691fda62016-08-12 00:43:162449 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522450 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042451 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162452
[email protected]49639fa2011-12-20 23:22:412453 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162454
bnc691fda62016-08-12 00:43:162455 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162457
2458 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012459 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162460
[email protected]58e32bb2013-01-21 18:23:252461 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162462 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252463 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2464 // The load timing after restart should have a new socket ID, and times after
2465 // those of the first load timing.
2466 EXPECT_LE(load_timing_info1.receive_headers_end,
2467 load_timing_info2.connect_timing.connect_start);
2468 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2469
sclittlefb249892015-09-10 21:33:222470 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162471 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222472 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162473 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192474
bnc691fda62016-08-12 00:43:162475 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522476 ASSERT_TRUE(response);
2477 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162478 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162479}
2480
ttuttled9dbc652015-09-29 20:00:592481// Test the request-challenge-retry sequence for basic auth.
2482// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012483TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592484 HttpRequestInfo request;
2485 request.method = "GET";
2486 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102487 request.traffic_annotation =
2488 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592489
2490 TestNetLog log;
2491 MockHostResolver* resolver = new MockHostResolver();
2492 session_deps_.net_log = &log;
2493 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092494 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162495 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592496
2497 resolver->rules()->ClearRules();
2498 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2499
2500 MockWrite data_writes1[] = {
2501 MockWrite("GET / HTTP/1.1\r\n"
2502 "Host: www.example.org\r\n"
2503 "Connection: keep-alive\r\n\r\n"),
2504 };
2505
2506 MockRead data_reads1[] = {
2507 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2508 // Give a couple authenticate options (only the middle one is actually
2509 // supported).
2510 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2511 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2512 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2513 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2514 // Large content-length -- won't matter, as connection will be reset.
2515 MockRead("Content-Length: 10000\r\n\r\n"),
2516 MockRead(SYNCHRONOUS, ERR_FAILED),
2517 };
2518
2519 // After calling trans->RestartWithAuth(), this is the request we should
2520 // be issuing -- the final header line contains the credentials.
2521 MockWrite data_writes2[] = {
2522 MockWrite("GET / HTTP/1.1\r\n"
2523 "Host: www.example.org\r\n"
2524 "Connection: keep-alive\r\n"
2525 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2526 };
2527
2528 // Lastly, the server responds with the actual content.
2529 MockRead data_reads2[] = {
2530 MockRead("HTTP/1.0 200 OK\r\n"),
2531 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2532 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2533 };
2534
2535 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2536 data_writes1, arraysize(data_writes1));
2537 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2538 data_writes2, arraysize(data_writes2));
2539 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2540 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2541
2542 TestCompletionCallback callback1;
2543
bnc691fda62016-08-12 00:43:162544 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202545 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592546
2547 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162548 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592549 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2550
2551 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162552 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592553 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162554 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592555
bnc691fda62016-08-12 00:43:162556 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592557 ASSERT_TRUE(response);
2558 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2559
2560 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162561 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592562 ASSERT_FALSE(endpoint.address().empty());
2563 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2564
2565 resolver->rules()->ClearRules();
2566 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2567
2568 TestCompletionCallback callback2;
2569
bnc691fda62016-08-12 00:43:162570 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592571 AuthCredentials(kFoo, kBar), callback2.callback())));
2572
2573 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162574 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592575 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2576 // The load timing after restart should have a new socket ID, and times after
2577 // those of the first load timing.
2578 EXPECT_LE(load_timing_info1.receive_headers_end,
2579 load_timing_info2.connect_timing.connect_start);
2580 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2581
2582 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162583 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592584 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162585 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592586
bnc691fda62016-08-12 00:43:162587 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592588 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522589 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592590 EXPECT_EQ(100, response->headers->GetContentLength());
2591
bnc691fda62016-08-12 00:43:162592 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592593 ASSERT_FALSE(endpoint.address().empty());
2594 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2595}
2596
David Benjamin83ddfb32018-03-30 01:07:522597// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2598// will eventually give up.
2599TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2600 HttpRequestInfo request;
2601 request.method = "GET";
2602 request.url = GURL("http://www.example.org/");
2603 request.traffic_annotation =
2604 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2605
2606 TestNetLog log;
2607 session_deps_.net_log = &log;
2608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2610
2611 MockWrite data_writes[] = {
2612 MockWrite("GET / HTTP/1.1\r\n"
2613 "Host: www.example.org\r\n"
2614 "Connection: keep-alive\r\n\r\n"),
2615 };
2616
2617 MockRead data_reads[] = {
2618 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2619 // Give a couple authenticate options (only the middle one is actually
2620 // supported).
2621 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2622 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2623 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2624 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2625 // Large content-length -- won't matter, as connection will be reset.
2626 MockRead("Content-Length: 10000\r\n\r\n"),
2627 MockRead(SYNCHRONOUS, ERR_FAILED),
2628 };
2629
2630 // After calling trans->RestartWithAuth(), this is the request we should
2631 // be issuing -- the final header line contains the credentials.
2632 MockWrite data_writes_restart[] = {
2633 MockWrite("GET / HTTP/1.1\r\n"
2634 "Host: www.example.org\r\n"
2635 "Connection: keep-alive\r\n"
2636 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2637 };
2638
2639 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2640 arraysize(data_writes));
2641 session_deps_.socket_factory->AddSocketDataProvider(&data);
2642
2643 TestCompletionCallback callback;
2644 int rv = callback.GetResult(
2645 trans.Start(&request, callback.callback(), NetLogWithSource()));
2646
2647 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2648 for (int i = 0; i < 32; i++) {
2649 // Check the previous response was a 401.
2650 EXPECT_THAT(rv, IsOk());
2651 const HttpResponseInfo* response = trans.GetResponseInfo();
2652 ASSERT_TRUE(response);
2653 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2654
2655 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
2656 data_reads, arraysize(data_reads), data_writes_restart,
2657 arraysize(data_writes_restart)));
2658 session_deps_.socket_factory->AddSocketDataProvider(
2659 data_restarts.back().get());
2660 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2661 callback.callback()));
2662 }
2663
2664 // After too many tries, the transaction should have given up.
2665 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2666}
2667
bncd16676a2016-07-20 16:23:012668TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462669 HttpRequestInfo request;
2670 request.method = "GET";
bncce36dca22015-04-21 22:11:232671 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292672 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102673 request.traffic_annotation =
2674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462675
danakj1fd259a02016-04-16 03:17:092676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272678
[email protected]861fcd52009-08-26 02:33:462679 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232680 MockWrite(
2681 "GET / HTTP/1.1\r\n"
2682 "Host: www.example.org\r\n"
2683 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462684 };
2685
2686 MockRead data_reads[] = {
2687 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2688 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2689 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2690 // Large content-length -- won't matter, as connection will be reset.
2691 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062692 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462693 };
2694
[email protected]31a2bfe2010-02-09 08:03:392695 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2696 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072697 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412698 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462699
tfarina42834112016-09-22 13:38:202700 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462702
2703 rv = callback.WaitForResult();
2704 EXPECT_EQ(0, rv);
2705
sclittlefb249892015-09-10 21:33:222706 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162707 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222708 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162709 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192710
bnc691fda62016-08-12 00:43:162711 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522712 ASSERT_TRUE(response);
2713 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462714}
2715
[email protected]2d2697f92009-02-18 21:00:322716// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2717// connection.
bncd16676a2016-07-20 16:23:012718TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182719 // On the second pass, the body read of the auth challenge is synchronous, so
2720 // IsConnectedAndIdle returns false. The socket should still be drained and
2721 // reused. See http://crbug.com/544255.
2722 for (int i = 0; i < 2; ++i) {
2723 HttpRequestInfo request;
2724 request.method = "GET";
2725 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102726 request.traffic_annotation =
2727 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322728
mmenkecc2298e2015-12-07 18:20:182729 TestNetLog log;
2730 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272732
mmenkecc2298e2015-12-07 18:20:182733 MockWrite data_writes[] = {
2734 MockWrite(ASYNC, 0,
2735 "GET / HTTP/1.1\r\n"
2736 "Host: www.example.org\r\n"
2737 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322738
bnc691fda62016-08-12 00:43:162739 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182740 // be issuing -- the final header line contains the credentials.
2741 MockWrite(ASYNC, 6,
2742 "GET / HTTP/1.1\r\n"
2743 "Host: www.example.org\r\n"
2744 "Connection: keep-alive\r\n"
2745 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2746 };
[email protected]2d2697f92009-02-18 21:00:322747
mmenkecc2298e2015-12-07 18:20:182748 MockRead data_reads[] = {
2749 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2750 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2751 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2752 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2753 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322754
mmenkecc2298e2015-12-07 18:20:182755 // Lastly, the server responds with the actual content.
2756 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2757 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2758 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2759 MockRead(ASYNC, 10, "Hello"),
2760 };
[email protected]2d2697f92009-02-18 21:00:322761
mmenkecc2298e2015-12-07 18:20:182762 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2763 arraysize(data_writes));
2764 data.set_busy_before_sync_reads(true);
2765 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462766
mmenkecc2298e2015-12-07 18:20:182767 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322768
bnc691fda62016-08-12 00:43:162769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202770 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012771 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322772
mmenkecc2298e2015-12-07 18:20:182773 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162774 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182775 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322776
bnc691fda62016-08-12 00:43:162777 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182778 ASSERT_TRUE(response);
2779 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322780
mmenkecc2298e2015-12-07 18:20:182781 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252782
bnc691fda62016-08-12 00:43:162783 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2784 callback2.callback());
robpercival214763f2016-07-01 23:27:012785 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322786
mmenkecc2298e2015-12-07 18:20:182787 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162788 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182789 TestLoadTimingReused(load_timing_info2);
2790 // The load timing after restart should have the same socket ID, and times
2791 // those of the first load timing.
2792 EXPECT_LE(load_timing_info1.receive_headers_end,
2793 load_timing_info2.send_start);
2794 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322795
bnc691fda62016-08-12 00:43:162796 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182797 ASSERT_TRUE(response);
2798 EXPECT_FALSE(response->auth_challenge);
2799 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322800
mmenkecc2298e2015-12-07 18:20:182801 std::string response_data;
bnc691fda62016-08-12 00:43:162802 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322803
mmenkecc2298e2015-12-07 18:20:182804 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162805 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182806 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162807 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182808 }
[email protected]2d2697f92009-02-18 21:00:322809}
2810
2811// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2812// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012813TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422814 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322815 request.method = "GET";
bncce36dca22015-04-21 22:11:232816 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102817 request.traffic_annotation =
2818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322819
danakj1fd259a02016-04-16 03:17:092820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272821
[email protected]2d2697f92009-02-18 21:00:322822 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162823 MockWrite("GET / HTTP/1.1\r\n"
2824 "Host: www.example.org\r\n"
2825 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322826
bnc691fda62016-08-12 00:43:162827 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232828 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162829 MockWrite("GET / HTTP/1.1\r\n"
2830 "Host: www.example.org\r\n"
2831 "Connection: keep-alive\r\n"
2832 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322833 };
2834
[email protected]2d2697f92009-02-18 21:00:322835 MockRead data_reads1[] = {
2836 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2837 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312838 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322839
2840 // Lastly, the server responds with the actual content.
2841 MockRead("HTTP/1.1 200 OK\r\n"),
2842 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502843 MockRead("Content-Length: 5\r\n\r\n"),
2844 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322845 };
2846
[email protected]2d0a4f92011-05-05 16:38:462847 // An incorrect reconnect would cause this to be read.
2848 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062849 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462850 };
2851
[email protected]31a2bfe2010-02-09 08:03:392852 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2853 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462854 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2855 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072856 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2857 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322858
[email protected]49639fa2011-12-20 23:22:412859 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322860
bnc691fda62016-08-12 00:43:162861 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202862 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322864
2865 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012866 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322867
bnc691fda62016-08-12 00:43:162868 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522869 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042870 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322871
[email protected]49639fa2011-12-20 23:22:412872 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322873
bnc691fda62016-08-12 00:43:162874 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322876
2877 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012878 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322879
bnc691fda62016-08-12 00:43:162880 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522881 ASSERT_TRUE(response);
2882 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502883 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322884}
2885
2886// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2887// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012888TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422889 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322890 request.method = "GET";
bncce36dca22015-04-21 22:11:232891 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102892 request.traffic_annotation =
2893 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322894
danakj1fd259a02016-04-16 03:17:092895 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272896
[email protected]2d2697f92009-02-18 21:00:322897 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162898 MockWrite("GET / HTTP/1.1\r\n"
2899 "Host: www.example.org\r\n"
2900 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322901
bnc691fda62016-08-12 00:43:162902 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232903 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162904 MockWrite("GET / HTTP/1.1\r\n"
2905 "Host: www.example.org\r\n"
2906 "Connection: keep-alive\r\n"
2907 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322908 };
2909
2910 // Respond with 5 kb of response body.
2911 std::string large_body_string("Unauthorized");
2912 large_body_string.append(5 * 1024, ' ');
2913 large_body_string.append("\r\n");
2914
2915 MockRead data_reads1[] = {
2916 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2917 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2918 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2919 // 5134 = 12 + 5 * 1024 + 2
2920 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062921 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322922
2923 // Lastly, the server responds with the actual content.
2924 MockRead("HTTP/1.1 200 OK\r\n"),
2925 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502926 MockRead("Content-Length: 5\r\n\r\n"),
2927 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322928 };
2929
[email protected]2d0a4f92011-05-05 16:38:462930 // An incorrect reconnect would cause this to be read.
2931 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062932 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462933 };
2934
[email protected]31a2bfe2010-02-09 08:03:392935 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2936 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462937 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2938 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072939 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2940 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322941
[email protected]49639fa2011-12-20 23:22:412942 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322943
bnc691fda62016-08-12 00:43:162944 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202945 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322947
2948 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012949 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322950
bnc691fda62016-08-12 00:43:162951 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522952 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042953 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322954
[email protected]49639fa2011-12-20 23:22:412955 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322956
bnc691fda62016-08-12 00:43:162957 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322959
2960 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012961 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322962
bnc691fda62016-08-12 00:43:162963 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522964 ASSERT_TRUE(response);
2965 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502966 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322967}
2968
2969// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312970// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012971TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312972 HttpRequestInfo request;
2973 request.method = "GET";
bncce36dca22015-04-21 22:11:232974 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102975 request.traffic_annotation =
2976 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:312977
danakj1fd259a02016-04-16 03:17:092978 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272979
[email protected]11203f012009-11-12 23:02:312980 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232981 MockWrite(
2982 "GET / HTTP/1.1\r\n"
2983 "Host: www.example.org\r\n"
2984 "Connection: keep-alive\r\n\r\n"),
2985 // This simulates the seemingly successful write to a closed connection
2986 // if the bug is not fixed.
2987 MockWrite(
2988 "GET / HTTP/1.1\r\n"
2989 "Host: www.example.org\r\n"
2990 "Connection: keep-alive\r\n"
2991 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312992 };
2993
2994 MockRead data_reads1[] = {
2995 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2996 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2997 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2998 MockRead("Content-Length: 14\r\n\r\n"),
2999 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063000 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313001 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063002 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313003 };
3004
bnc691fda62016-08-12 00:43:163005 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313006 // be issuing -- the final header line contains the credentials.
3007 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233008 MockWrite(
3009 "GET / HTTP/1.1\r\n"
3010 "Host: www.example.org\r\n"
3011 "Connection: keep-alive\r\n"
3012 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313013 };
3014
3015 // Lastly, the server responds with the actual content.
3016 MockRead data_reads2[] = {
3017 MockRead("HTTP/1.1 200 OK\r\n"),
3018 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503019 MockRead("Content-Length: 5\r\n\r\n"),
3020 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313021 };
3022
[email protected]31a2bfe2010-02-09 08:03:393023 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3024 data_writes1, arraysize(data_writes1));
3025 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3026 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073027 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3028 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313029
[email protected]49639fa2011-12-20 23:22:413030 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313031
bnc691fda62016-08-12 00:43:163032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203033 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313035
3036 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013037 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313038
bnc691fda62016-08-12 00:43:163039 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523040 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043041 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313042
[email protected]49639fa2011-12-20 23:22:413043 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313044
bnc691fda62016-08-12 00:43:163045 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313047
3048 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013049 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313050
bnc691fda62016-08-12 00:43:163051 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523052 ASSERT_TRUE(response);
3053 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503054 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313055}
3056
[email protected]394816e92010-08-03 07:38:593057// Test the request-challenge-retry sequence for basic auth, over a connection
3058// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013059TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013060 HttpRequestInfo request;
3061 request.method = "GET";
bncce36dca22015-04-21 22:11:233062 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013063 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293064 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103065 request.traffic_annotation =
3066 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013067
3068 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593069 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493070 ProxyResolutionService::CreateFixedFromPacResult(
3071 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513072 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013073 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013075
3076 // Since we have proxy, should try to establish tunnel.
3077 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543078 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173079 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543080 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013081 };
3082
mmenkee71e15332015-10-07 16:39:543083 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013084 // connection.
3085 MockRead data_reads1[] = {
3086 // No credentials.
3087 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3088 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543089 };
ttuttle34f63b52015-03-05 04:33:013090
mmenkee71e15332015-10-07 16:39:543091 // Since the first connection couldn't be reused, need to establish another
3092 // once given credentials.
3093 MockWrite data_writes2[] = {
3094 // After calling trans->RestartWithAuth(), this is the request we should
3095 // be issuing -- the final header line contains the credentials.
3096 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173097 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543098 "Proxy-Connection: keep-alive\r\n"
3099 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3100
3101 MockWrite("GET / HTTP/1.1\r\n"
3102 "Host: www.example.org\r\n"
3103 "Connection: keep-alive\r\n\r\n"),
3104 };
3105
3106 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013107 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3108
3109 MockRead("HTTP/1.1 200 OK\r\n"),
3110 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3111 MockRead("Content-Length: 5\r\n\r\n"),
3112 MockRead(SYNCHRONOUS, "hello"),
3113 };
3114
3115 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3116 data_writes1, arraysize(data_writes1));
3117 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543118 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3119 data_writes2, arraysize(data_writes2));
3120 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013121 SSLSocketDataProvider ssl(ASYNC, OK);
3122 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3123
3124 TestCompletionCallback callback1;
3125
bnc87dcefc2017-05-25 12:47:583126 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193127 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013128
3129 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013131
3132 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013133 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463134 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013135 log.GetEntries(&entries);
3136 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003137 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3138 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013139 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003140 entries, pos,
3141 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3142 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013143
3144 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523145 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013146 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523147 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013148 EXPECT_EQ(407, response->headers->response_code());
3149 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3150 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3151
3152 LoadTimingInfo load_timing_info;
3153 // CONNECT requests and responses are handled at the connect job level, so
3154 // the transaction does not yet have a connection.
3155 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3156
3157 TestCompletionCallback callback2;
3158
3159 rv =
3160 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013162
3163 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013164 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013165
3166 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523167 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013168
3169 EXPECT_TRUE(response->headers->IsKeepAlive());
3170 EXPECT_EQ(200, response->headers->response_code());
3171 EXPECT_EQ(5, response->headers->GetContentLength());
3172 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3173
3174 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523175 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013176
3177 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3178 TestLoadTimingNotReusedWithPac(load_timing_info,
3179 CONNECT_TIMING_HAS_SSL_TIMES);
3180
3181 trans.reset();
3182 session->CloseAllConnections();
3183}
3184
3185// Test the request-challenge-retry sequence for basic auth, over a connection
3186// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013187TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593188 HttpRequestInfo request;
3189 request.method = "GET";
bncce36dca22015-04-21 22:11:233190 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593191 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293192 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103193 request.traffic_annotation =
3194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593195
[email protected]cb9bf6ca2011-01-28 13:15:273196 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593197 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493198 ProxyResolutionService::CreateFixedFromPacResult(
3199 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513200 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073201 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273203
[email protected]394816e92010-08-03 07:38:593204 // Since we have proxy, should try to establish tunnel.
3205 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543206 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173207 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543208 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113209 };
3210
mmenkee71e15332015-10-07 16:39:543211 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083212 // connection.
3213 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543214 // No credentials.
3215 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3216 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3217 MockRead("Proxy-Connection: close\r\n\r\n"),
3218 };
mmenkee0b5c882015-08-26 20:29:113219
mmenkee71e15332015-10-07 16:39:543220 MockWrite data_writes2[] = {
3221 // After calling trans->RestartWithAuth(), this is the request we should
3222 // be issuing -- the final header line contains the credentials.
3223 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173224 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543225 "Proxy-Connection: keep-alive\r\n"
3226 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083227
mmenkee71e15332015-10-07 16:39:543228 MockWrite("GET / HTTP/1.1\r\n"
3229 "Host: www.example.org\r\n"
3230 "Connection: keep-alive\r\n\r\n"),
3231 };
3232
3233 MockRead data_reads2[] = {
3234 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3235
3236 MockRead("HTTP/1.1 200 OK\r\n"),
3237 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3238 MockRead("Content-Length: 5\r\n\r\n"),
3239 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593240 };
3241
3242 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3243 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073244 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543245 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3246 data_writes2, arraysize(data_writes2));
3247 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063248 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593250
[email protected]49639fa2011-12-20 23:22:413251 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593252
bnc87dcefc2017-05-25 12:47:583253 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193254 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503255
[email protected]49639fa2011-12-20 23:22:413256 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593258
3259 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013260 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463261 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403262 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593263 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003264 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3265 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593266 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403267 entries, pos,
mikecirone8b85c432016-09-08 19:11:003268 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3269 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593270
3271 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523272 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013273 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523274 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593275 EXPECT_EQ(407, response->headers->response_code());
3276 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043277 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593278
[email protected]029c83b62013-01-24 05:28:203279 LoadTimingInfo load_timing_info;
3280 // CONNECT requests and responses are handled at the connect job level, so
3281 // the transaction does not yet have a connection.
3282 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3283
[email protected]49639fa2011-12-20 23:22:413284 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593285
[email protected]49639fa2011-12-20 23:22:413286 rv = trans->RestartWithAuth(
3287 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593289
3290 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013291 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593292
3293 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523294 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593295
3296 EXPECT_TRUE(response->headers->IsKeepAlive());
3297 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503298 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593299 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3300
3301 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523302 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503303
[email protected]029c83b62013-01-24 05:28:203304 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3305 TestLoadTimingNotReusedWithPac(load_timing_info,
3306 CONNECT_TIMING_HAS_SSL_TIMES);
3307
[email protected]0b0bf032010-09-21 18:08:503308 trans.reset();
[email protected]102e27c2011-02-23 01:01:313309 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593310}
3311
[email protected]11203f012009-11-12 23:02:313312// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013313// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013314TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233315 // On the second pass, the body read of the auth challenge is synchronous, so
3316 // IsConnectedAndIdle returns false. The socket should still be drained and
3317 // reused. See http://crbug.com/544255.
3318 for (int i = 0; i < 2; ++i) {
3319 HttpRequestInfo request;
3320 request.method = "GET";
3321 request.url = GURL("https://www.example.org/");
3322 // Ensure that proxy authentication is attempted even
3323 // when the no authentication data flag is set.
3324 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103325 request.traffic_annotation =
3326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013327
mmenked39192ee2015-12-09 00:57:233328 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593329 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493330 ProxyResolutionService::CreateFixed("myproxy:70",
3331 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233332 BoundTestNetLog log;
3333 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093334 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013335
bnc691fda62016-08-12 00:43:163336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013337
mmenked39192ee2015-12-09 00:57:233338 // Since we have proxy, should try to establish tunnel.
3339 MockWrite data_writes1[] = {
3340 MockWrite(ASYNC, 0,
3341 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3342 "Host: www.example.org:443\r\n"
3343 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013344
bnc691fda62016-08-12 00:43:163345 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233346 // be issuing -- the final header line contains the credentials.
3347 MockWrite(ASYNC, 3,
3348 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3349 "Host: www.example.org:443\r\n"
3350 "Proxy-Connection: keep-alive\r\n"
3351 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3352 };
ttuttle34f63b52015-03-05 04:33:013353
mmenked39192ee2015-12-09 00:57:233354 // The proxy responds to the connect with a 407, using a persistent
3355 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3356 MockRead data_reads1[] = {
3357 // No credentials.
3358 MockRead(ASYNC, 1,
3359 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3360 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3361 "Proxy-Connection: keep-alive\r\n"
3362 "Content-Length: 10\r\n\r\n"),
3363 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013364
mmenked39192ee2015-12-09 00:57:233365 // Wrong credentials (wrong password).
3366 MockRead(ASYNC, 4,
3367 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3368 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3369 "Proxy-Connection: keep-alive\r\n"
3370 "Content-Length: 10\r\n\r\n"),
3371 // No response body because the test stops reading here.
3372 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3373 };
ttuttle34f63b52015-03-05 04:33:013374
mmenked39192ee2015-12-09 00:57:233375 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3376 arraysize(data_writes1));
3377 data1.set_busy_before_sync_reads(true);
3378 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013379
mmenked39192ee2015-12-09 00:57:233380 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013381
bnc691fda62016-08-12 00:43:163382 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013383 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013384
mmenked39192ee2015-12-09 00:57:233385 TestNetLogEntry::List entries;
3386 log.GetEntries(&entries);
3387 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003388 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3389 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233390 ExpectLogContainsSomewhere(
3391 entries, pos,
mikecirone8b85c432016-09-08 19:11:003392 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3393 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013394
bnc691fda62016-08-12 00:43:163395 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233396 ASSERT_TRUE(response);
3397 ASSERT_TRUE(response->headers);
3398 EXPECT_TRUE(response->headers->IsKeepAlive());
3399 EXPECT_EQ(407, response->headers->response_code());
3400 EXPECT_EQ(10, response->headers->GetContentLength());
3401 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3402 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013403
mmenked39192ee2015-12-09 00:57:233404 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013405
mmenked39192ee2015-12-09 00:57:233406 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163407 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3408 callback2.callback());
robpercival214763f2016-07-01 23:27:013409 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013410
bnc691fda62016-08-12 00:43:163411 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233412 ASSERT_TRUE(response);
3413 ASSERT_TRUE(response->headers);
3414 EXPECT_TRUE(response->headers->IsKeepAlive());
3415 EXPECT_EQ(407, response->headers->response_code());
3416 EXPECT_EQ(10, response->headers->GetContentLength());
3417 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3418 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013419
mmenked39192ee2015-12-09 00:57:233420 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3421 // out of scope.
3422 session->CloseAllConnections();
3423 }
ttuttle34f63b52015-03-05 04:33:013424}
3425
3426// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3427// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013428TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233429 // On the second pass, the body read of the auth challenge is synchronous, so
3430 // IsConnectedAndIdle returns false. The socket should still be drained and
3431 // reused. See http://crbug.com/544255.
3432 for (int i = 0; i < 2; ++i) {
3433 HttpRequestInfo request;
3434 request.method = "GET";
3435 request.url = GURL("https://www.example.org/");
3436 // Ensure that proxy authentication is attempted even
3437 // when the no authentication data flag is set.
3438 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103439 request.traffic_annotation =
3440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233441
3442 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593443 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493444 ProxyResolutionService::CreateFixed("myproxy:70",
3445 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233446 BoundTestNetLog log;
3447 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233449
bnc691fda62016-08-12 00:43:163450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233451
3452 // Since we have proxy, should try to establish tunnel.
3453 MockWrite data_writes1[] = {
3454 MockWrite(ASYNC, 0,
3455 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3456 "Host: www.example.org:443\r\n"
3457 "Proxy-Connection: keep-alive\r\n\r\n"),
3458
bnc691fda62016-08-12 00:43:163459 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233460 // be issuing -- the final header line contains the credentials.
3461 MockWrite(ASYNC, 3,
3462 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3463 "Host: www.example.org:443\r\n"
3464 "Proxy-Connection: keep-alive\r\n"
3465 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3466 };
3467
3468 // The proxy responds to the connect with a 407, using a persistent
3469 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3470 MockRead data_reads1[] = {
3471 // No credentials.
3472 MockRead(ASYNC, 1,
3473 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3474 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3475 "Content-Length: 10\r\n\r\n"),
3476 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3477
3478 // Wrong credentials (wrong password).
3479 MockRead(ASYNC, 4,
3480 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3481 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3482 "Content-Length: 10\r\n\r\n"),
3483 // No response body because the test stops reading here.
3484 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3485 };
3486
3487 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3488 arraysize(data_writes1));
3489 data1.set_busy_before_sync_reads(true);
3490 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3491
3492 TestCompletionCallback callback1;
3493
bnc691fda62016-08-12 00:43:163494 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013495 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233496
3497 TestNetLogEntry::List entries;
3498 log.GetEntries(&entries);
3499 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003500 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3501 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233502 ExpectLogContainsSomewhere(
3503 entries, pos,
mikecirone8b85c432016-09-08 19:11:003504 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3505 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233506
bnc691fda62016-08-12 00:43:163507 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233508 ASSERT_TRUE(response);
3509 ASSERT_TRUE(response->headers);
3510 EXPECT_TRUE(response->headers->IsKeepAlive());
3511 EXPECT_EQ(407, response->headers->response_code());
3512 EXPECT_EQ(10, response->headers->GetContentLength());
3513 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3514 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3515
3516 TestCompletionCallback callback2;
3517
3518 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163519 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3520 callback2.callback());
robpercival214763f2016-07-01 23:27:013521 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233522
bnc691fda62016-08-12 00:43:163523 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233524 ASSERT_TRUE(response);
3525 ASSERT_TRUE(response->headers);
3526 EXPECT_TRUE(response->headers->IsKeepAlive());
3527 EXPECT_EQ(407, response->headers->response_code());
3528 EXPECT_EQ(10, response->headers->GetContentLength());
3529 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3530 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3531
3532 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3533 // out of scope.
3534 session->CloseAllConnections();
3535 }
3536}
3537
3538// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3539// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3540// the case the server sends extra data on the original socket, so it can't be
3541// reused.
bncd16676a2016-07-20 16:23:013542TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273543 HttpRequestInfo request;
3544 request.method = "GET";
bncce36dca22015-04-21 22:11:233545 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273546 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293547 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103548 request.traffic_annotation =
3549 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273550
[email protected]2d2697f92009-02-18 21:00:323551 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593552 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493553 ProxyResolutionService::CreateFixedFromPacResult(
3554 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513555 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073556 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323558
[email protected]2d2697f92009-02-18 21:00:323559 // Since we have proxy, should try to establish tunnel.
3560 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233561 MockWrite(ASYNC, 0,
3562 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173563 "Host: www.example.org:443\r\n"
3564 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233565 };
[email protected]2d2697f92009-02-18 21:00:323566
mmenked39192ee2015-12-09 00:57:233567 // The proxy responds to the connect with a 407, using a persistent, but sends
3568 // extra data, so the socket cannot be reused.
3569 MockRead data_reads1[] = {
3570 // No credentials.
3571 MockRead(ASYNC, 1,
3572 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3573 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3574 "Content-Length: 10\r\n\r\n"),
3575 MockRead(SYNCHRONOUS, 2, "0123456789"),
3576 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3577 };
3578
3579 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233580 // After calling trans->RestartWithAuth(), this is the request we should
3581 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233582 MockWrite(ASYNC, 0,
3583 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173584 "Host: www.example.org:443\r\n"
3585 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233586 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3587
3588 MockWrite(ASYNC, 2,
3589 "GET / HTTP/1.1\r\n"
3590 "Host: www.example.org\r\n"
3591 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323592 };
3593
mmenked39192ee2015-12-09 00:57:233594 MockRead data_reads2[] = {
3595 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323596
mmenked39192ee2015-12-09 00:57:233597 MockRead(ASYNC, 3,
3598 "HTTP/1.1 200 OK\r\n"
3599 "Content-Type: text/html; charset=iso-8859-1\r\n"
3600 "Content-Length: 5\r\n\r\n"),
3601 // No response body because the test stops reading here.
3602 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323603 };
3604
mmenked39192ee2015-12-09 00:57:233605 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3606 arraysize(data_writes1));
3607 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073608 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233609 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3610 arraysize(data_writes2));
3611 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3612 SSLSocketDataProvider ssl(ASYNC, OK);
3613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323614
[email protected]49639fa2011-12-20 23:22:413615 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323616
bnc87dcefc2017-05-25 12:47:583617 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193618 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323619
mmenked39192ee2015-12-09 00:57:233620 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013621 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233622
mmenke43758e62015-05-04 21:09:463623 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403624 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393625 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003626 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3627 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393628 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403629 entries, pos,
mikecirone8b85c432016-09-08 19:11:003630 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3631 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323632
[email protected]1c773ea12009-04-28 19:58:423633 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243634 ASSERT_TRUE(response);
3635 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323636 EXPECT_TRUE(response->headers->IsKeepAlive());
3637 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423638 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043639 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323640
mmenked39192ee2015-12-09 00:57:233641 LoadTimingInfo load_timing_info;
3642 // CONNECT requests and responses are handled at the connect job level, so
3643 // the transaction does not yet have a connection.
3644 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3645
[email protected]49639fa2011-12-20 23:22:413646 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323647
mmenked39192ee2015-12-09 00:57:233648 rv =
3649 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013650 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323651
[email protected]2d2697f92009-02-18 21:00:323652 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233653 EXPECT_EQ(200, response->headers->response_code());
3654 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423655 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133656
mmenked39192ee2015-12-09 00:57:233657 // The password prompt info should not be set.
3658 EXPECT_FALSE(response->auth_challenge);
3659
3660 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3661 TestLoadTimingNotReusedWithPac(load_timing_info,
3662 CONNECT_TIMING_HAS_SSL_TIMES);
3663
3664 trans.reset();
[email protected]102e27c2011-02-23 01:01:313665 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323666}
3667
mmenkee71e15332015-10-07 16:39:543668// Test the case a proxy closes a socket while the challenge body is being
3669// drained.
bncd16676a2016-07-20 16:23:013670TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543671 HttpRequestInfo request;
3672 request.method = "GET";
3673 request.url = GURL("https://www.example.org/");
3674 // Ensure that proxy authentication is attempted even
3675 // when the no authentication data flag is set.
3676 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103677 request.traffic_annotation =
3678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543679
3680 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493681 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3682 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093683 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543684
bnc691fda62016-08-12 00:43:163685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543686
3687 // Since we have proxy, should try to establish tunnel.
3688 MockWrite data_writes1[] = {
3689 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173690 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543691 "Proxy-Connection: keep-alive\r\n\r\n"),
3692 };
3693
3694 // The proxy responds to the connect with a 407, using a persistent
3695 // connection.
3696 MockRead data_reads1[] = {
3697 // No credentials.
3698 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3699 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3700 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3701 // Server hands up in the middle of the body.
3702 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3703 };
3704
3705 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163706 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543707 // be issuing -- the final header line contains the credentials.
3708 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173709 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543710 "Proxy-Connection: keep-alive\r\n"
3711 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3712
3713 MockWrite("GET / HTTP/1.1\r\n"
3714 "Host: www.example.org\r\n"
3715 "Connection: keep-alive\r\n\r\n"),
3716 };
3717
3718 MockRead data_reads2[] = {
3719 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3720
3721 MockRead("HTTP/1.1 200 OK\r\n"),
3722 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3723 MockRead("Content-Length: 5\r\n\r\n"),
3724 MockRead(SYNCHRONOUS, "hello"),
3725 };
3726
3727 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3728 data_writes1, arraysize(data_writes1));
3729 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3730 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3731 data_writes2, arraysize(data_writes2));
3732 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3733 SSLSocketDataProvider ssl(ASYNC, OK);
3734 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3735
3736 TestCompletionCallback callback;
3737
tfarina42834112016-09-22 13:38:203738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013739 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543740
bnc691fda62016-08-12 00:43:163741 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543742 ASSERT_TRUE(response);
3743 ASSERT_TRUE(response->headers);
3744 EXPECT_TRUE(response->headers->IsKeepAlive());
3745 EXPECT_EQ(407, response->headers->response_code());
3746 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3747
bnc691fda62016-08-12 00:43:163748 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013749 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543750
bnc691fda62016-08-12 00:43:163751 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543752 ASSERT_TRUE(response);
3753 ASSERT_TRUE(response->headers);
3754 EXPECT_TRUE(response->headers->IsKeepAlive());
3755 EXPECT_EQ(200, response->headers->response_code());
3756 std::string body;
bnc691fda62016-08-12 00:43:163757 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543758 EXPECT_EQ("hello", body);
3759}
3760
[email protected]a8e9b162009-03-12 00:06:443761// Test that we don't read the response body when we fail to establish a tunnel,
3762// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013763TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273764 HttpRequestInfo request;
3765 request.method = "GET";
bncce36dca22015-04-21 22:11:233766 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103767 request.traffic_annotation =
3768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273769
[email protected]a8e9b162009-03-12 00:06:443770 // 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);
[email protected]a8e9b162009-03-12 00:06:443773
danakj1fd259a02016-04-16 03:17:093774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443775
bnc691fda62016-08-12 00:43:163776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443777
[email protected]a8e9b162009-03-12 00:06:443778 // 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"),
[email protected]a8e9b162009-03-12 00:06:443783 };
3784
3785 // The proxy responds to the connect with a 407.
3786 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243787 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3788 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3789 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233790 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243791 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443792 };
3793
[email protected]31a2bfe2010-02-09 08:03:393794 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3795 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073796 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443797
[email protected]49639fa2011-12-20 23:22:413798 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443799
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));
[email protected]a8e9b162009-03-12 00:06:443802
3803 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013804 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443805
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);
[email protected]a8e9b162009-03-12 00:06:443809 EXPECT_TRUE(response->headers->IsKeepAlive());
3810 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423811 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443812
3813 std::string response_data;
bnc691fda62016-08-12 00:43:163814 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013815 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183816
3817 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313818 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443819}
3820
ttuttle7933c112015-01-06 00:55:243821// Test that we don't pass extraneous headers from the proxy's response to the
3822// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013823TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243824 HttpRequestInfo request;
3825 request.method = "GET";
bncce36dca22015-04-21 22:11:233826 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103827 request.traffic_annotation =
3828 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243829
3830 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493831 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3832 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243833
danakj1fd259a02016-04-16 03:17:093834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243835
bnc691fda62016-08-12 00:43:163836 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243837
3838 // Since we have proxy, should try to establish tunnel.
3839 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173840 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3841 "Host: www.example.org:443\r\n"
3842 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243843 };
3844
3845 // The proxy responds to the connect with a 407.
3846 MockRead data_reads[] = {
3847 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3848 MockRead("X-Foo: bar\r\n"),
3849 MockRead("Set-Cookie: foo=bar\r\n"),
3850 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3851 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233852 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243853 };
3854
3855 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3856 arraysize(data_writes));
3857 session_deps_.socket_factory->AddSocketDataProvider(&data);
3858
3859 TestCompletionCallback callback;
3860
tfarina42834112016-09-22 13:38:203861 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243863
3864 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013865 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243866
bnc691fda62016-08-12 00:43:163867 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243868 ASSERT_TRUE(response);
3869 ASSERT_TRUE(response->headers);
3870 EXPECT_TRUE(response->headers->IsKeepAlive());
3871 EXPECT_EQ(407, response->headers->response_code());
3872 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3873 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3874 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3875
3876 std::string response_data;
bnc691fda62016-08-12 00:43:163877 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013878 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243879
3880 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3881 session->CloseAllConnections();
3882}
3883
[email protected]8fdbcd22010-05-05 02:54:523884// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3885// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013886TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523887 HttpRequestInfo request;
3888 request.method = "GET";
bncce36dca22015-04-21 22:11:233889 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103890 request.traffic_annotation =
3891 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523892
[email protected]cb9bf6ca2011-01-28 13:15:273893 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273896
[email protected]8fdbcd22010-05-05 02:54:523897 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233898 MockWrite(
3899 "GET / HTTP/1.1\r\n"
3900 "Host: www.example.org\r\n"
3901 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523902 };
3903
3904 MockRead data_reads1[] = {
3905 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3906 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3907 // Large content-length -- won't matter, as connection will be reset.
3908 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063909 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523910 };
3911
3912 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3913 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073914 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523915
[email protected]49639fa2011-12-20 23:22:413916 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523917
tfarina42834112016-09-22 13:38:203918 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523920
3921 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013922 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523923}
3924
[email protected]7a67a8152010-11-05 18:31:103925// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3926// through a non-authenticating proxy. The request should fail with
3927// ERR_UNEXPECTED_PROXY_AUTH.
3928// Note that it is impossible to detect if an HTTP server returns a 407 through
3929// a non-authenticating proxy - there is nothing to indicate whether the
3930// response came from the proxy or the server, so it is treated as if the proxy
3931// issued the challenge.
bncd16676a2016-07-20 16:23:013932TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273933 HttpRequestInfo request;
3934 request.method = "GET";
bncce36dca22015-04-21 22:11:233935 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103936 request.traffic_annotation =
3937 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273938
Ramin Halavatica8d5252018-03-12 05:33:493939 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3940 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513941 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073942 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103944
[email protected]7a67a8152010-11-05 18:31:103945 // Since we have proxy, should try to establish tunnel.
3946 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173947 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3948 "Host: www.example.org:443\r\n"
3949 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103950
rsleevidb16bb02015-11-12 23:47:173951 MockWrite("GET / HTTP/1.1\r\n"
3952 "Host: www.example.org\r\n"
3953 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103954 };
3955
3956 MockRead data_reads1[] = {
3957 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3958
3959 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3960 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3961 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063962 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103963 };
3964
3965 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3966 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073967 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063968 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103970
[email protected]49639fa2011-12-20 23:22:413971 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103972
bnc691fda62016-08-12 00:43:163973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103974
bnc691fda62016-08-12 00:43:163975 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103977
3978 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013979 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463980 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403981 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103982 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003983 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3984 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103985 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403986 entries, pos,
mikecirone8b85c432016-09-08 19:11:003987 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3988 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103989}
[email protected]2df19bb2010-08-25 20:13:463990
mmenke2a1781d2015-10-07 19:25:333991// Test a proxy auth scheme that allows default credentials and a proxy server
3992// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013993TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333994 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3995 HttpRequestInfo request;
3996 request.method = "GET";
3997 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103998 request.traffic_annotation =
3999 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334000
4001 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594002 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494003 ProxyResolutionService::CreateFixedFromPacResult(
4004 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334005
Jeremy Roman0579ed62017-08-29 15:56:194006 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334007 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194008 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334009 mock_handler->set_allows_default_credentials(true);
4010 auth_handler_factory->AddMockHandler(mock_handler.release(),
4011 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484012 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334013
4014 // Add NetLog just so can verify load timing information gets a NetLog ID.
4015 NetLog net_log;
4016 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094017 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334018
4019 // Since we have proxy, should try to establish tunnel.
4020 MockWrite data_writes1[] = {
4021 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174022 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334023 "Proxy-Connection: keep-alive\r\n\r\n"),
4024 };
4025
4026 // The proxy responds to the connect with a 407, using a non-persistent
4027 // connection.
4028 MockRead data_reads1[] = {
4029 // No credentials.
4030 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4031 MockRead("Proxy-Authenticate: Mock\r\n"),
4032 MockRead("Proxy-Connection: close\r\n\r\n"),
4033 };
4034
4035 // Since the first connection couldn't be reused, need to establish another
4036 // once given credentials.
4037 MockWrite data_writes2[] = {
4038 // After calling trans->RestartWithAuth(), this is the request we should
4039 // be issuing -- the final header line contains the credentials.
4040 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174041 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334042 "Proxy-Connection: keep-alive\r\n"
4043 "Proxy-Authorization: auth_token\r\n\r\n"),
4044
4045 MockWrite("GET / HTTP/1.1\r\n"
4046 "Host: www.example.org\r\n"
4047 "Connection: keep-alive\r\n\r\n"),
4048 };
4049
4050 MockRead data_reads2[] = {
4051 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4052
4053 MockRead("HTTP/1.1 200 OK\r\n"),
4054 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4055 MockRead("Content-Length: 5\r\n\r\n"),
4056 MockRead(SYNCHRONOUS, "hello"),
4057 };
4058
4059 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4060 data_writes1, arraysize(data_writes1));
4061 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4062 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4063 data_writes2, arraysize(data_writes2));
4064 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4065 SSLSocketDataProvider ssl(ASYNC, OK);
4066 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4067
bnc87dcefc2017-05-25 12:47:584068 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194069 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334070
4071 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204072 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014073 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334074
4075 const HttpResponseInfo* response = trans->GetResponseInfo();
4076 ASSERT_TRUE(response);
4077 ASSERT_TRUE(response->headers);
4078 EXPECT_FALSE(response->headers->IsKeepAlive());
4079 EXPECT_EQ(407, response->headers->response_code());
4080 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4081 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524082 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334083
4084 LoadTimingInfo load_timing_info;
4085 // CONNECT requests and responses are handled at the connect job level, so
4086 // the transaction does not yet have a connection.
4087 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4088
4089 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014090 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334091 response = trans->GetResponseInfo();
4092 ASSERT_TRUE(response);
4093 ASSERT_TRUE(response->headers);
4094 EXPECT_TRUE(response->headers->IsKeepAlive());
4095 EXPECT_EQ(200, response->headers->response_code());
4096 EXPECT_EQ(5, response->headers->GetContentLength());
4097 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4098
4099 // The password prompt info should not be set.
4100 EXPECT_FALSE(response->auth_challenge);
4101
4102 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4103 TestLoadTimingNotReusedWithPac(load_timing_info,
4104 CONNECT_TIMING_HAS_SSL_TIMES);
4105
4106 trans.reset();
4107 session->CloseAllConnections();
4108}
4109
4110// Test a proxy auth scheme that allows default credentials and a proxy server
4111// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014112TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334113 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4114 HttpRequestInfo request;
4115 request.method = "GET";
4116 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104117 request.traffic_annotation =
4118 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334119
4120 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594121 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494122 ProxyResolutionService::CreateFixedFromPacResult(
4123 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334124
Jeremy Roman0579ed62017-08-29 15:56:194125 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334126 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194127 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334128 mock_handler->set_allows_default_credentials(true);
4129 auth_handler_factory->AddMockHandler(mock_handler.release(),
4130 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484131 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334132
4133 // Add NetLog just so can verify load timing information gets a NetLog ID.
4134 NetLog net_log;
4135 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094136 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334137
4138 // Should try to establish tunnel.
4139 MockWrite data_writes1[] = {
4140 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174141 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334142 "Proxy-Connection: keep-alive\r\n\r\n"),
4143
4144 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174145 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334146 "Proxy-Connection: keep-alive\r\n"
4147 "Proxy-Authorization: auth_token\r\n\r\n"),
4148 };
4149
4150 // The proxy responds to the connect with a 407, using a non-persistent
4151 // connection.
4152 MockRead data_reads1[] = {
4153 // No credentials.
4154 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4155 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4156 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4157 };
4158
4159 // Since the first connection was closed, need to establish another once given
4160 // credentials.
4161 MockWrite data_writes2[] = {
4162 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174163 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334164 "Proxy-Connection: keep-alive\r\n"
4165 "Proxy-Authorization: auth_token\r\n\r\n"),
4166
4167 MockWrite("GET / HTTP/1.1\r\n"
4168 "Host: www.example.org\r\n"
4169 "Connection: keep-alive\r\n\r\n"),
4170 };
4171
4172 MockRead data_reads2[] = {
4173 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4174
4175 MockRead("HTTP/1.1 200 OK\r\n"),
4176 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4177 MockRead("Content-Length: 5\r\n\r\n"),
4178 MockRead(SYNCHRONOUS, "hello"),
4179 };
4180
4181 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4182 data_writes1, arraysize(data_writes1));
4183 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4184 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4185 data_writes2, arraysize(data_writes2));
4186 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4187 SSLSocketDataProvider ssl(ASYNC, OK);
4188 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4189
bnc87dcefc2017-05-25 12:47:584190 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194191 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334192
4193 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204194 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014195 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334196
4197 const HttpResponseInfo* response = trans->GetResponseInfo();
4198 ASSERT_TRUE(response);
4199 ASSERT_TRUE(response->headers);
4200 EXPECT_TRUE(response->headers->IsKeepAlive());
4201 EXPECT_EQ(407, response->headers->response_code());
4202 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4203 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4204 EXPECT_FALSE(response->auth_challenge);
4205
4206 LoadTimingInfo load_timing_info;
4207 // CONNECT requests and responses are handled at the connect job level, so
4208 // the transaction does not yet have a connection.
4209 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4210
4211 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014212 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334213
4214 response = trans->GetResponseInfo();
4215 ASSERT_TRUE(response);
4216 ASSERT_TRUE(response->headers);
4217 EXPECT_TRUE(response->headers->IsKeepAlive());
4218 EXPECT_EQ(200, response->headers->response_code());
4219 EXPECT_EQ(5, response->headers->GetContentLength());
4220 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4221
4222 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524223 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334224
4225 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4226 TestLoadTimingNotReusedWithPac(load_timing_info,
4227 CONNECT_TIMING_HAS_SSL_TIMES);
4228
4229 trans.reset();
4230 session->CloseAllConnections();
4231}
4232
4233// Test a proxy auth scheme that allows default credentials and a proxy server
4234// that hangs up when credentials are initially sent, and hangs up again when
4235// they are retried.
bncd16676a2016-07-20 16:23:014236TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334237 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4238 HttpRequestInfo request;
4239 request.method = "GET";
4240 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104241 request.traffic_annotation =
4242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334243
4244 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594245 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494246 ProxyResolutionService::CreateFixedFromPacResult(
4247 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334248
Jeremy Roman0579ed62017-08-29 15:56:194249 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334250 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194251 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334252 mock_handler->set_allows_default_credentials(true);
4253 auth_handler_factory->AddMockHandler(mock_handler.release(),
4254 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484255 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334256
4257 // Add NetLog just so can verify load timing information gets a NetLog ID.
4258 NetLog net_log;
4259 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094260 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334261
4262 // Should try to establish tunnel.
4263 MockWrite data_writes1[] = {
4264 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174265 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334266 "Proxy-Connection: keep-alive\r\n\r\n"),
4267
4268 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174269 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334270 "Proxy-Connection: keep-alive\r\n"
4271 "Proxy-Authorization: auth_token\r\n\r\n"),
4272 };
4273
4274 // The proxy responds to the connect with a 407, and then hangs up after the
4275 // second request is sent.
4276 MockRead data_reads1[] = {
4277 // No credentials.
4278 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4279 MockRead("Content-Length: 0\r\n"),
4280 MockRead("Proxy-Connection: keep-alive\r\n"),
4281 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4282 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4283 };
4284
4285 // HttpNetworkTransaction sees a reused connection that was closed with
4286 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4287 // request.
4288 MockWrite data_writes2[] = {
4289 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174290 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334291 "Proxy-Connection: keep-alive\r\n\r\n"),
4292 };
4293
4294 // The proxy, having had more than enough of us, just hangs up.
4295 MockRead data_reads2[] = {
4296 // No credentials.
4297 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4298 };
4299
4300 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4301 data_writes1, arraysize(data_writes1));
4302 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4303 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4304 data_writes2, arraysize(data_writes2));
4305 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4306
bnc87dcefc2017-05-25 12:47:584307 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194308 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334309
4310 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204311 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014312 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334313
4314 const HttpResponseInfo* response = trans->GetResponseInfo();
4315 ASSERT_TRUE(response);
4316 ASSERT_TRUE(response->headers);
4317 EXPECT_TRUE(response->headers->IsKeepAlive());
4318 EXPECT_EQ(407, response->headers->response_code());
4319 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4320 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4321 EXPECT_FALSE(response->auth_challenge);
4322
4323 LoadTimingInfo load_timing_info;
4324 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4325
4326 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014327 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334328
4329 trans.reset();
4330 session->CloseAllConnections();
4331}
4332
4333// Test a proxy auth scheme that allows default credentials and a proxy server
4334// that hangs up when credentials are initially sent, and sends a challenge
4335// again they are retried.
bncd16676a2016-07-20 16:23:014336TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334337 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4338 HttpRequestInfo request;
4339 request.method = "GET";
4340 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104341 request.traffic_annotation =
4342 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334343
4344 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594345 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494346 ProxyResolutionService::CreateFixedFromPacResult(
4347 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334348
Jeremy Roman0579ed62017-08-29 15:56:194349 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334350 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194351 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334352 mock_handler->set_allows_default_credentials(true);
4353 auth_handler_factory->AddMockHandler(mock_handler.release(),
4354 HttpAuth::AUTH_PROXY);
4355 // Add another handler for the second challenge. It supports default
4356 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194357 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334358 mock_handler->set_allows_default_credentials(true);
4359 auth_handler_factory->AddMockHandler(mock_handler.release(),
4360 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484361 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334362
4363 // Add NetLog just so can verify load timing information gets a NetLog ID.
4364 NetLog net_log;
4365 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094366 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334367
4368 // Should try to establish tunnel.
4369 MockWrite data_writes1[] = {
4370 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174371 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334372 "Proxy-Connection: keep-alive\r\n\r\n"),
4373 };
4374
4375 // The proxy responds to the connect with a 407, using a non-persistent
4376 // connection.
4377 MockRead data_reads1[] = {
4378 // No credentials.
4379 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4380 MockRead("Proxy-Authenticate: Mock\r\n"),
4381 MockRead("Proxy-Connection: close\r\n\r\n"),
4382 };
4383
4384 // Since the first connection was closed, need to establish another once given
4385 // credentials.
4386 MockWrite data_writes2[] = {
4387 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174388 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334389 "Proxy-Connection: keep-alive\r\n"
4390 "Proxy-Authorization: auth_token\r\n\r\n"),
4391 };
4392
4393 MockRead data_reads2[] = {
4394 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4395 MockRead("Proxy-Authenticate: Mock\r\n"),
4396 MockRead("Proxy-Connection: close\r\n\r\n"),
4397 };
4398
4399 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4400 data_writes1, arraysize(data_writes1));
4401 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4402 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4403 data_writes2, arraysize(data_writes2));
4404 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4405 SSLSocketDataProvider ssl(ASYNC, OK);
4406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4407
bnc87dcefc2017-05-25 12:47:584408 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194409 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334410
4411 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204412 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014413 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334414
4415 const HttpResponseInfo* response = trans->GetResponseInfo();
4416 ASSERT_TRUE(response);
4417 ASSERT_TRUE(response->headers);
4418 EXPECT_EQ(407, response->headers->response_code());
4419 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4420 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4421 EXPECT_FALSE(response->auth_challenge);
4422
4423 LoadTimingInfo load_timing_info;
4424 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4425
4426 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014427 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334428 response = trans->GetResponseInfo();
4429 ASSERT_TRUE(response);
4430 ASSERT_TRUE(response->headers);
4431 EXPECT_EQ(407, response->headers->response_code());
4432 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4433 EXPECT_TRUE(response->auth_challenge);
4434
4435 trans.reset();
4436 session->CloseAllConnections();
4437}
4438
asankae2257db2016-10-11 22:03:164439// A more nuanced test than GenerateAuthToken test which asserts that
4440// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4441// unnecessarily invalidated, and that if the server co-operates, the
4442// authentication handshake can continue with the same scheme but with a
4443// different identity.
4444TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4445 HttpRequestInfo request;
4446 request.method = "GET";
4447 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104448 request.traffic_annotation =
4449 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164450
Jeremy Roman0579ed62017-08-29 15:56:194451 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164452 auth_handler_factory->set_do_init_from_challenge(true);
4453
4454 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194455 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164456 mock_handler->set_allows_default_credentials(true);
4457 mock_handler->set_allows_explicit_credentials(true);
4458 mock_handler->set_connection_based(true);
4459 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4460 auth_handler_factory->AddMockHandler(mock_handler.release(),
4461 HttpAuth::AUTH_SERVER);
4462
4463 // Add another handler for the second challenge. It supports default
4464 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194465 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164466 mock_handler->set_allows_default_credentials(true);
4467 mock_handler->set_allows_explicit_credentials(true);
4468 mock_handler->set_connection_based(true);
4469 auth_handler_factory->AddMockHandler(mock_handler.release(),
4470 HttpAuth::AUTH_SERVER);
4471 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4472
4473 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4474
4475 MockWrite data_writes1[] = {
4476 MockWrite("GET / HTTP/1.1\r\n"
4477 "Host: www.example.org\r\n"
4478 "Connection: keep-alive\r\n\r\n"),
4479 };
4480
4481 MockRead data_reads1[] = {
4482 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4483 "WWW-Authenticate: Mock\r\n"
4484 "Connection: keep-alive\r\n\r\n"),
4485 };
4486
4487 // Identical to data_writes1[]. The AuthHandler encounters a
4488 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4489 // transaction procceds without an authorization header.
4490 MockWrite data_writes2[] = {
4491 MockWrite("GET / HTTP/1.1\r\n"
4492 "Host: www.example.org\r\n"
4493 "Connection: keep-alive\r\n\r\n"),
4494 };
4495
4496 MockRead data_reads2[] = {
4497 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4498 "WWW-Authenticate: Mock\r\n"
4499 "Connection: keep-alive\r\n\r\n"),
4500 };
4501
4502 MockWrite data_writes3[] = {
4503 MockWrite("GET / HTTP/1.1\r\n"
4504 "Host: www.example.org\r\n"
4505 "Connection: keep-alive\r\n"
4506 "Authorization: auth_token\r\n\r\n"),
4507 };
4508
4509 MockRead data_reads3[] = {
4510 MockRead("HTTP/1.1 200 OK\r\n"
4511 "Content-Length: 5\r\n"
4512 "Content-Type: text/plain\r\n"
4513 "Connection: keep-alive\r\n\r\n"
4514 "Hello"),
4515 };
4516
4517 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4518 data_writes1, arraysize(data_writes1));
4519 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4520
4521 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4522 data_writes2, arraysize(data_writes2));
4523 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4524
4525 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4526 data_writes3, arraysize(data_writes3));
4527 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4528
bnc87dcefc2017-05-25 12:47:584529 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194530 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164531
4532 TestCompletionCallback callback;
4533 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4534 EXPECT_THAT(callback.GetResult(rv), IsOk());
4535
4536 const HttpResponseInfo* response = trans->GetResponseInfo();
4537 ASSERT_TRUE(response);
4538 ASSERT_TRUE(response->headers);
4539 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4540
4541 // The following three tests assert that an authentication challenge was
4542 // received and that the stack is ready to respond to the challenge using
4543 // ambient credentials.
4544 EXPECT_EQ(401, response->headers->response_code());
4545 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4546 EXPECT_FALSE(response->auth_challenge);
4547
4548 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4549 EXPECT_THAT(callback.GetResult(rv), IsOk());
4550 response = trans->GetResponseInfo();
4551 ASSERT_TRUE(response);
4552 ASSERT_TRUE(response->headers);
4553
4554 // The following three tests assert that an authentication challenge was
4555 // received and that the stack needs explicit credentials before it is ready
4556 // to respond to the challenge.
4557 EXPECT_EQ(401, response->headers->response_code());
4558 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4559 EXPECT_TRUE(response->auth_challenge);
4560
4561 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4562 EXPECT_THAT(callback.GetResult(rv), IsOk());
4563 response = trans->GetResponseInfo();
4564 ASSERT_TRUE(response);
4565 ASSERT_TRUE(response->headers);
4566 EXPECT_EQ(200, response->headers->response_code());
4567
4568 trans.reset();
4569 session->CloseAllConnections();
4570}
4571
Matt Menked1eb6d42018-01-17 04:54:064572// Proxy resolver that returns a proxy with the same host and port for different
4573// schemes, based on the path of the URL being requests.
4574class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4575 public:
4576 SameProxyWithDifferentSchemesProxyResolver() {}
4577 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4578
4579 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4580
4581 static HostPortPair ProxyHostPortPair() {
4582 return HostPortPair::FromString(ProxyHostPortPairAsString());
4583 }
4584
4585 // ProxyResolver implementation.
4586 int GetProxyForURL(const GURL& url,
4587 ProxyInfo* results,
4588 const CompletionCallback& callback,
4589 std::unique_ptr<Request>* request,
4590 const NetLogWithSource& /*net_log*/) override {
4591 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574592 results->set_traffic_annotation(
4593 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064594 if (url.path() == "/socks4") {
4595 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4596 return OK;
4597 }
4598 if (url.path() == "/socks5") {
4599 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4600 return OK;
4601 }
4602 if (url.path() == "/http") {
4603 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4604 return OK;
4605 }
4606 if (url.path() == "/https") {
4607 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4608 return OK;
4609 }
4610 NOTREACHED();
4611 return ERR_NOT_IMPLEMENTED;
4612 }
4613
4614 private:
4615 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4616};
4617
4618class SameProxyWithDifferentSchemesProxyResolverFactory
4619 : public ProxyResolverFactory {
4620 public:
4621 SameProxyWithDifferentSchemesProxyResolverFactory()
4622 : ProxyResolverFactory(false) {}
4623
Lily Houghton99597862018-03-07 16:40:424624 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4625 std::unique_ptr<ProxyResolver>* resolver,
4626 const CompletionCallback& callback,
4627 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064628 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4629 return OK;
4630 }
4631
4632 private:
4633 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4634};
4635
4636// Check that when different proxy schemes are all applied to a proxy at the
4637// same address, the sonnections are not grouped together. i.e., a request to
4638// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4639// request to foo.com using proxy.com as an HTTP proxy.
4640TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494641 session_deps_.proxy_resolution_service =
4642 std::make_unique<ProxyResolutionService>(
4643 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4644 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4645 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4646 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064647
4648 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4649
4650 MockWrite socks_writes[] = {
4651 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4652 kSOCKS4OkRequestLocalHostPort80Length),
4653 MockWrite(SYNCHRONOUS,
4654 "GET /socks4 HTTP/1.1\r\n"
4655 "Host: test\r\n"
4656 "Connection: keep-alive\r\n\r\n"),
4657 };
4658 MockRead socks_reads[] = {
4659 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4660 MockRead("HTTP/1.0 200 OK\r\n"
4661 "Connection: keep-alive\r\n"
4662 "Content-Length: 15\r\n\r\n"
4663 "SOCKS4 Response"),
4664 };
4665 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4666 socks_writes, arraysize(socks_writes));
4667 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4668
4669 const char kSOCKS5Request[] = {
4670 0x05, // Version
4671 0x01, // Command (CONNECT)
4672 0x00, // Reserved
4673 0x03, // Address type (DOMAINNAME)
4674 0x04, // Length of domain (4)
4675 't', 'e', 's', 't', // Domain string
4676 0x00, 0x50, // 16-bit port (80)
4677 };
4678 MockWrite socks5_writes[] = {
4679 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4680 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4681 MockWrite(SYNCHRONOUS,
4682 "GET /socks5 HTTP/1.1\r\n"
4683 "Host: test\r\n"
4684 "Connection: keep-alive\r\n\r\n"),
4685 };
4686 MockRead socks5_reads[] = {
4687 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4688 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4689 MockRead("HTTP/1.0 200 OK\r\n"
4690 "Connection: keep-alive\r\n"
4691 "Content-Length: 15\r\n\r\n"
4692 "SOCKS5 Response"),
4693 };
4694 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4695 socks5_writes, arraysize(socks5_writes));
4696 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4697
4698 MockWrite http_writes[] = {
4699 MockWrite(SYNCHRONOUS,
4700 "GET http://test/http HTTP/1.1\r\n"
4701 "Host: test\r\n"
4702 "Proxy-Connection: keep-alive\r\n\r\n"),
4703 };
4704 MockRead http_reads[] = {
4705 MockRead("HTTP/1.1 200 OK\r\n"
4706 "Proxy-Connection: keep-alive\r\n"
4707 "Content-Length: 13\r\n\r\n"
4708 "HTTP Response"),
4709 };
4710 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4711 http_writes, arraysize(http_writes));
4712 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4713
4714 MockWrite https_writes[] = {
4715 MockWrite(SYNCHRONOUS,
4716 "GET http://test/https HTTP/1.1\r\n"
4717 "Host: test\r\n"
4718 "Proxy-Connection: keep-alive\r\n\r\n"),
4719 };
4720 MockRead https_reads[] = {
4721 MockRead("HTTP/1.1 200 OK\r\n"
4722 "Proxy-Connection: keep-alive\r\n"
4723 "Content-Length: 14\r\n\r\n"
4724 "HTTPS Response"),
4725 };
4726 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4727 https_writes, arraysize(https_writes));
4728 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4729 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4730 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4731
4732 struct TestCase {
4733 GURL url;
4734 std::string expected_response;
4735 // How many idle sockets there should be in the SOCKS proxy socket pool
4736 // after the test.
4737 int expected_idle_socks_sockets;
4738 // How many idle sockets there should be in the HTTP proxy socket pool after
4739 // the test.
4740 int expected_idle_http_sockets;
4741 } const kTestCases[] = {
4742 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4743 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4744 {GURL("http://test/http"), "HTTP Response", 2, 1},
4745 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4746 };
4747
4748 for (const auto& test_case : kTestCases) {
4749 HttpRequestInfo request;
4750 request.method = "GET";
4751 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:104752 request.traffic_annotation =
4753 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064754 std::unique_ptr<HttpNetworkTransaction> trans =
4755 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4756 session.get());
4757 TestCompletionCallback callback;
4758 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4759 EXPECT_THAT(callback.GetResult(rv), IsOk());
4760
4761 const HttpResponseInfo* response = trans->GetResponseInfo();
4762 ASSERT_TRUE(response);
4763 ASSERT_TRUE(response->headers);
4764 EXPECT_EQ(200, response->headers->response_code());
4765 std::string response_data;
4766 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4767 EXPECT_EQ(test_case.expected_response, response_data);
4768
4769 // Return the socket to the socket pool, so can make sure it's not used for
4770 // the next requests.
4771 trans.reset();
4772 base::RunLoop().RunUntilIdle();
4773
4774 // Check the number of idle sockets in the pool, to make sure that used
4775 // sockets are indeed being returned to the socket pool. If each request
4776 // doesn't return an idle socket to the pool, the test would incorrectly
4777 // pass.
4778 EXPECT_EQ(
4779 test_case.expected_idle_socks_sockets,
4780 session
4781 ->GetSocketPoolForSOCKSProxy(
4782 HttpNetworkSession::NORMAL_SOCKET_POOL,
4783 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4784 ->IdleSocketCount());
4785 EXPECT_EQ(
4786 test_case.expected_idle_http_sockets,
4787 session
4788 ->GetSocketPoolForHTTPProxy(
4789 HttpNetworkSession::NORMAL_SOCKET_POOL,
4790 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4791 ->IdleSocketCount());
4792 }
4793}
4794
[email protected]029c83b62013-01-24 05:28:204795// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014796TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204797 HttpRequestInfo request1;
4798 request1.method = "GET";
bncce36dca22015-04-21 22:11:234799 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104800 request1.traffic_annotation =
4801 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204802
4803 HttpRequestInfo request2;
4804 request2.method = "GET";
bncce36dca22015-04-21 22:11:234805 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104806 request2.traffic_annotation =
4807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204808
4809 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494810 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4811 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514812 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074813 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204815
4816 // Since we have proxy, should try to establish tunnel.
4817 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174818 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4819 "Host: www.example.org:443\r\n"
4820 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204821
rsleevidb16bb02015-11-12 23:47:174822 MockWrite("GET /1 HTTP/1.1\r\n"
4823 "Host: www.example.org\r\n"
4824 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204825
rsleevidb16bb02015-11-12 23:47:174826 MockWrite("GET /2 HTTP/1.1\r\n"
4827 "Host: www.example.org\r\n"
4828 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204829 };
4830
4831 // The proxy responds to the connect with a 407, using a persistent
4832 // connection.
4833 MockRead data_reads1[] = {
4834 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4835
4836 MockRead("HTTP/1.1 200 OK\r\n"),
4837 MockRead("Content-Length: 1\r\n\r\n"),
4838 MockRead(SYNCHRONOUS, "1"),
4839
4840 MockRead("HTTP/1.1 200 OK\r\n"),
4841 MockRead("Content-Length: 2\r\n\r\n"),
4842 MockRead(SYNCHRONOUS, "22"),
4843 };
4844
4845 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4846 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074847 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204848 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204850
4851 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584852 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194853 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204854
4855 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204857
4858 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014859 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204860
4861 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524862 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474863 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524864 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204865 EXPECT_EQ(1, response1->headers->GetContentLength());
4866
4867 LoadTimingInfo load_timing_info1;
4868 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4869 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4870
4871 trans1.reset();
4872
4873 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584874 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204876
4877 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204879
4880 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014881 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204882
4883 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524884 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474885 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524886 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204887 EXPECT_EQ(2, response2->headers->GetContentLength());
4888
4889 LoadTimingInfo load_timing_info2;
4890 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4891 TestLoadTimingReused(load_timing_info2);
4892
4893 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4894
4895 trans2.reset();
4896 session->CloseAllConnections();
4897}
4898
4899// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014900TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204901 HttpRequestInfo request1;
4902 request1.method = "GET";
bncce36dca22015-04-21 22:11:234903 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104904 request1.traffic_annotation =
4905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204906
4907 HttpRequestInfo request2;
4908 request2.method = "GET";
bncce36dca22015-04-21 22:11:234909 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104910 request2.traffic_annotation =
4911 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204912
4913 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594914 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494915 ProxyResolutionService::CreateFixedFromPacResult(
4916 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514917 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074918 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204920
4921 // Since we have proxy, should try to establish tunnel.
4922 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174923 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4924 "Host: www.example.org:443\r\n"
4925 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204926
rsleevidb16bb02015-11-12 23:47:174927 MockWrite("GET /1 HTTP/1.1\r\n"
4928 "Host: www.example.org\r\n"
4929 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204930
rsleevidb16bb02015-11-12 23:47:174931 MockWrite("GET /2 HTTP/1.1\r\n"
4932 "Host: www.example.org\r\n"
4933 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204934 };
4935
4936 // The proxy responds to the connect with a 407, using a persistent
4937 // connection.
4938 MockRead data_reads1[] = {
4939 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4940
4941 MockRead("HTTP/1.1 200 OK\r\n"),
4942 MockRead("Content-Length: 1\r\n\r\n"),
4943 MockRead(SYNCHRONOUS, "1"),
4944
4945 MockRead("HTTP/1.1 200 OK\r\n"),
4946 MockRead("Content-Length: 2\r\n\r\n"),
4947 MockRead(SYNCHRONOUS, "22"),
4948 };
4949
4950 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4951 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204953 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074954 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204955
4956 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584957 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194958 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204959
4960 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204962
4963 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014964 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204965
4966 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524967 ASSERT_TRUE(response1);
4968 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204969 EXPECT_EQ(1, response1->headers->GetContentLength());
4970
4971 LoadTimingInfo load_timing_info1;
4972 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4973 TestLoadTimingNotReusedWithPac(load_timing_info1,
4974 CONNECT_TIMING_HAS_SSL_TIMES);
4975
4976 trans1.reset();
4977
4978 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584979 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194980 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204981
4982 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204984
4985 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014986 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204987
4988 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524989 ASSERT_TRUE(response2);
4990 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204991 EXPECT_EQ(2, response2->headers->GetContentLength());
4992
4993 LoadTimingInfo load_timing_info2;
4994 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4995 TestLoadTimingReusedWithPac(load_timing_info2);
4996
4997 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4998
4999 trans2.reset();
5000 session->CloseAllConnections();
5001}
5002
[email protected]2df19bb2010-08-25 20:13:465003// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015004TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275005 HttpRequestInfo request;
5006 request.method = "GET";
bncce36dca22015-04-21 22:11:235007 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105008 request.traffic_annotation =
5009 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275010
[email protected]2df19bb2010-08-25 20:13:465011 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495012 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5013 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515014 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075015 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095016 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465017
[email protected]2df19bb2010-08-25 20:13:465018 // Since we have proxy, should use full url
5019 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235020 MockWrite(
5021 "GET http://www.example.org/ HTTP/1.1\r\n"
5022 "Host: www.example.org\r\n"
5023 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465024 };
5025
5026 MockRead data_reads1[] = {
5027 MockRead("HTTP/1.1 200 OK\r\n"),
5028 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5029 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065030 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465031 };
5032
5033 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5034 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075035 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065036 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075037 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465038
[email protected]49639fa2011-12-20 23:22:415039 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465040
bnc691fda62016-08-12 00:43:165041 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505042
bnc691fda62016-08-12 00:43:165043 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465045
5046 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015047 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465048
[email protected]58e32bb2013-01-21 18:23:255049 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165050 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255051 TestLoadTimingNotReused(load_timing_info,
5052 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5053
bnc691fda62016-08-12 00:43:165054 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525055 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465056
tbansal2ecbbc72016-10-06 17:15:475057 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465058 EXPECT_TRUE(response->headers->IsKeepAlive());
5059 EXPECT_EQ(200, response->headers->response_code());
5060 EXPECT_EQ(100, response->headers->GetContentLength());
5061 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5062
5063 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525064 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465065}
5066
[email protected]7642b5ae2010-09-01 20:55:175067// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015068TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275069 HttpRequestInfo request;
5070 request.method = "GET";
bncce36dca22015-04-21 22:11:235071 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105072 request.traffic_annotation =
5073 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275074
[email protected]7642b5ae2010-09-01 20:55:175075 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495076 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5077 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515078 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075079 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095080 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175081
bncce36dca22015-04-21 22:11:235082 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415083 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455084 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415085 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175086
bnc42331402016-07-25 13:36:155087 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415088 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175089 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415090 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175091 };
5092
rch8e6c6c42015-05-01 14:05:135093 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5094 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075095 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175096
[email protected]8ddf8322012-02-23 18:08:065097 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365098 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175100
[email protected]49639fa2011-12-20 23:22:415101 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175102
bnc691fda62016-08-12 00:43:165103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505104
bnc691fda62016-08-12 00:43:165105 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175107
5108 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015109 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175110
[email protected]58e32bb2013-01-21 18:23:255111 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165112 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255113 TestLoadTimingNotReused(load_timing_info,
5114 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5115
bnc691fda62016-08-12 00:43:165116 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525117 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475118 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525119 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025120 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175121
5122 std::string response_data;
bnc691fda62016-08-12 00:43:165123 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235124 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175125}
5126
[email protected]1c173852014-06-19 12:51:505127// Verifies that a session which races and wins against the owning transaction
5128// (completing prior to host resolution), doesn't fail the transaction.
5129// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015130TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505131 HttpRequestInfo request;
5132 request.method = "GET";
bncce36dca22015-04-21 22:11:235133 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105134 request.traffic_annotation =
5135 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505136
5137 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495138 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5139 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515140 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505141 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505143
bncce36dca22015-04-21 22:11:235144 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415145 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455146 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415147 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505148
bnc42331402016-07-25 13:36:155149 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415150 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505151 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415152 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505153 };
5154
rch8e6c6c42015-05-01 14:05:135155 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5156 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505157 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5158
5159 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365160 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5162
5163 TestCompletionCallback callback1;
5164
bnc691fda62016-08-12 00:43:165165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505166
5167 // Stall the hostname resolution begun by the transaction.
5168 session_deps_.host_resolver->set_synchronous_mode(false);
5169 session_deps_.host_resolver->set_ondemand_mode(true);
5170
bnc691fda62016-08-12 00:43:165171 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505173
5174 // Race a session to the proxy, which completes first.
5175 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045176 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5177 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505178 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525179 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505180
5181 // Unstall the resolution begun by the transaction.
5182 session_deps_.host_resolver->set_ondemand_mode(true);
5183 session_deps_.host_resolver->ResolveAllPending();
5184
5185 EXPECT_FALSE(callback1.have_result());
5186 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015187 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505188
bnc691fda62016-08-12 00:43:165189 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525190 ASSERT_TRUE(response);
5191 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025192 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505193
5194 std::string response_data;
bnc691fda62016-08-12 00:43:165195 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505196 EXPECT_EQ(kUploadData, response_data);
5197}
5198
[email protected]dc7bd1c52010-11-12 00:01:135199// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015200TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275201 HttpRequestInfo request;
5202 request.method = "GET";
bncce36dca22015-04-21 22:11:235203 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105204 request.traffic_annotation =
5205 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275206
[email protected]79cb5c12011-09-12 13:12:045207 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495208 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5209 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515210 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075211 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095212 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135213
[email protected]dc7bd1c52010-11-12 00:01:135214 // The first request will be a bare GET, the second request will be a
5215 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455216 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415217 SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485218 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385219 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135220 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465221 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135222 };
bncdf80d44fd2016-07-15 20:27:415223 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5224 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485225 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135226 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415227 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135228 };
5229
5230 // The first response is a 407 proxy authentication challenge, and the second
5231 // response will be a 200 response since the second request includes a valid
5232 // Authorization header.
5233 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465234 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135235 };
bnc42331402016-07-25 13:36:155236 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235237 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415238 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5239 SpdySerializedFrame body_authentication(
5240 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155241 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415242 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135243 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415244 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465245 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415246 CreateMockRead(resp_data, 4),
5247 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135248 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135249 };
5250
rch8e6c6c42015-05-01 14:05:135251 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5252 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075253 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135254
[email protected]8ddf8322012-02-23 18:08:065255 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365256 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135258
[email protected]49639fa2011-12-20 23:22:415259 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135260
bnc691fda62016-08-12 00:43:165261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135262
bnc691fda62016-08-12 00:43:165263 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135265
5266 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015267 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135268
bnc691fda62016-08-12 00:43:165269 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135270
wezca1070932016-05-26 20:30:525271 ASSERT_TRUE(response);
5272 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135273 EXPECT_EQ(407, response->headers->response_code());
5274 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435275 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135276
[email protected]49639fa2011-12-20 23:22:415277 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135278
bnc691fda62016-08-12 00:43:165279 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135281
5282 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015283 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135284
bnc691fda62016-08-12 00:43:165285 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135286
wezca1070932016-05-26 20:30:525287 ASSERT_TRUE(response_restart);
5288 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135289 EXPECT_EQ(200, response_restart->headers->response_code());
5290 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525291 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135292}
5293
[email protected]d9da5fe2010-10-13 22:37:165294// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015295TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[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 Halavatib5e433e2018-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 HTTP
[email protected]d9da5fe2010-10-13 22:37:165315
bncce36dca22015-04-21 22:11:235316 const char get[] =
5317 "GET / HTTP/1.1\r\n"
5318 "Host: www.example.org\r\n"
5319 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415320 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195321 spdy_util_.ConstructSpdyDataFrame(1, get, false));
bnc42331402016-07-25 13:36:155322 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165323 const char resp[] = "HTTP/1.1 200 OK\r\n"
5324 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415325 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195326 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
bncdf80d44fd2016-07-15 20:27:415327 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195328 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
bncdf80d44fd2016-07-15 20:27:415329 SpdySerializedFrame window_update(
5330 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.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, 6),
[email protected]8d2f7012012-02-16 00:08:045335 };
5336
[email protected]d9da5fe2010-10-13 22:37:165337 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415338 CreateMockRead(conn_resp, 1, ASYNC),
5339 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5340 CreateMockRead(wrapped_body, 4, ASYNC),
5341 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135342 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165343 };
5344
rch8e6c6c42015-05-01 14:05:135345 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5346 arraysize(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);
[email protected]bb88e1d32013-05-03 23:11:075353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165354
[email protected]49639fa2011-12-20 23:22:415355 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165356
bnc691fda62016-08-12 00:43:165357 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165359
5360 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015361 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165362
[email protected]58e32bb2013-01-21 18:23:255363 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165364 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255365 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5366
bnc691fda62016-08-12 00:43:165367 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525368 ASSERT_TRUE(response);
5369 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165370 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5371
5372 std::string response_data;
bnc691fda62016-08-12 00:43:165373 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165374 EXPECT_EQ("1234567890", response_data);
5375}
5376
5377// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015378TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5379 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385380
[email protected]cb9bf6ca2011-01-28 13:15:275381 HttpRequestInfo request;
5382 request.method = "GET";
bncce36dca22015-04-21 22:11:235383 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105384 request.traffic_annotation =
5385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275386
[email protected]d9da5fe2010-10-13 22:37:165387 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495388 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5389 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515390 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075391 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165393
bnc691fda62016-08-12 00:43:165394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165395
bncce36dca22015-04-21 22:11:235396 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415397 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235398 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5399 // fetch https://www.example.org/ via SPDY
5400 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415401 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495402 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415403 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155404 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415405 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155406 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415407 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025408 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415409 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5410 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025411 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415412 SpdySerializedFrame window_update_get_resp(
5413 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5414 SpdySerializedFrame window_update_body(
5415 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045416
5417 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415418 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5419 CreateMockWrite(window_update_get_resp, 6),
5420 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045421 };
5422
[email protected]d9da5fe2010-10-13 22:37:165423 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415424 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095425 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415426 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5427 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135428 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165429 };
5430
rch32320842015-05-16 15:57:095431 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5432 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075433 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165434
[email protected]8ddf8322012-02-23 18:08:065435 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365436 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065438 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365439 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165441
[email protected]49639fa2011-12-20 23:22:415442 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165443
bnc691fda62016-08-12 00:43:165444 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165446
rch32320842015-05-16 15:57:095447 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555448 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095449 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595450 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165451 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015452 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165453
[email protected]58e32bb2013-01-21 18:23:255454 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165455 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255456 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5457
bnc691fda62016-08-12 00:43:165458 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525459 ASSERT_TRUE(response);
5460 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025461 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165462
5463 std::string response_data;
bnc691fda62016-08-12 00:43:165464 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235465 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165466}
5467
5468// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015469TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275470 HttpRequestInfo request;
5471 request.method = "GET";
bncce36dca22015-04-21 22:11:235472 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105473 request.traffic_annotation =
5474 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275475
[email protected]d9da5fe2010-10-13 22:37:165476 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495477 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5478 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515479 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075480 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165482
bnc691fda62016-08-12 00:43:165483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165484
bncce36dca22015-04-21 22:11:235485 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415486 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235487 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415488 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085489 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165490
5491 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415492 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165493 };
5494
bnc42331402016-07-25 13:36:155495 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415496 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165497 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415498 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165499 };
5500
rch8e6c6c42015-05-01 14:05:135501 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5502 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075503 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165504
[email protected]8ddf8322012-02-23 18:08:065505 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365506 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065508 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365509 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075510 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165511
[email protected]49639fa2011-12-20 23:22:415512 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165513
bnc691fda62016-08-12 00:43:165514 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015515 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165516
5517 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015518 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165519
ttuttle960fcbf2016-04-19 13:26:325520 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165521}
5522
[email protected]f6c63db52013-02-02 00:35:225523// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5524// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015525TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225526 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5527 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495528 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5529 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515530 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075531 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095532 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505533 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225534
5535 HttpRequestInfo request1;
5536 request1.method = "GET";
bncce36dca22015-04-21 22:11:235537 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225538 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105539 request1.traffic_annotation =
5540 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225541
5542 HttpRequestInfo request2;
5543 request2.method = "GET";
bncce36dca22015-04-21 22:11:235544 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225545 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105546 request2.traffic_annotation =
5547 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225548
bncce36dca22015-04-21 22:11:235549 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415550 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235551 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155552 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225553
bncce36dca22015-04-21 22:11:235554 // Fetch https://www.example.org/ via HTTP.
5555 const char get1[] =
5556 "GET / HTTP/1.1\r\n"
5557 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225558 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415559 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195560 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225561 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5562 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415563 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195564 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415565 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195566 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415567 SpdySerializedFrame window_update(
5568 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225569
bncce36dca22015-04-21 22:11:235570 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295571 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275572 connect2_block[kHttp2MethodHeader] = "CONNECT";
5573 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155574 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5575 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395576
bnc42331402016-07-25 13:36:155577 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225578
bncce36dca22015-04-21 22:11:235579 // Fetch https://mail.example.org/ via HTTP.
5580 const char get2[] =
5581 "GET / HTTP/1.1\r\n"
5582 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225583 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415584 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195585 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225586 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5587 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415588 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195589 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
bncdf80d44fd2016-07-15 20:27:415590 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195591 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225592
5593 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415594 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5595 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225596 };
5597
5598 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415599 CreateMockRead(conn_resp1, 1, ASYNC),
5600 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5601 CreateMockRead(wrapped_body1, 4, ASYNC),
5602 CreateMockRead(conn_resp2, 6, ASYNC),
5603 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5604 CreateMockRead(wrapped_body2, 9, ASYNC),
5605 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225606 };
5607
mmenke11eb5152015-06-09 14:50:505608 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5609 arraysize(spdy_writes));
5610 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225611
5612 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365613 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225615 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225617 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505618 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225619
5620 TestCompletionCallback callback;
5621
bnc691fda62016-08-12 00:43:165622 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205623 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015624 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225625
5626 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165627 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225628 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5629
bnc691fda62016-08-12 00:43:165630 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525631 ASSERT_TRUE(response);
5632 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225633 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5634
5635 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295636 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165637 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505638 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225639
bnc691fda62016-08-12 00:43:165640 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205641 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015642 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225643
5644 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165645 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225646 // Even though the SPDY connection is reused, a new tunnelled connection has
5647 // to be created, so the socket's load timing looks like a fresh connection.
5648 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5649
5650 // The requests should have different IDs, since they each are using their own
5651 // separate stream.
5652 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5653
bnc691fda62016-08-12 00:43:165654 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505655 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225656}
5657
5658// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5659// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225661 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5662 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495663 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5664 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515665 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075666 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095667 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505668 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225669
5670 HttpRequestInfo request1;
5671 request1.method = "GET";
bncce36dca22015-04-21 22:11:235672 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225673 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105674 request1.traffic_annotation =
5675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225676
5677 HttpRequestInfo request2;
5678 request2.method = "GET";
bncce36dca22015-04-21 22:11:235679 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225680 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105681 request2.traffic_annotation =
5682 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225683
bncce36dca22015-04-21 22:11:235684 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415685 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235686 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155687 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225688
bncce36dca22015-04-21 22:11:235689 // Fetch https://www.example.org/ via HTTP.
5690 const char get1[] =
5691 "GET / HTTP/1.1\r\n"
5692 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225693 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415694 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195695 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225696 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5697 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415698 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195699 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415700 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195701 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415702 SpdySerializedFrame window_update(
5703 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225704
bncce36dca22015-04-21 22:11:235705 // Fetch https://www.example.org/2 via HTTP.
5706 const char get2[] =
5707 "GET /2 HTTP/1.1\r\n"
5708 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225709 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415710 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195711 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225712 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5713 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415714 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195715 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
bncdf80d44fd2016-07-15 20:27:415716 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195717 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225718
5719 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415720 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5721 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225722 };
5723
5724 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415725 CreateMockRead(conn_resp1, 1, ASYNC),
5726 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465727 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415728 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465729 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415730 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225731 };
5732
mmenke11eb5152015-06-09 14:50:505733 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5734 arraysize(spdy_writes));
5735 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225736
5737 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365738 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225740 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505741 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225742
5743 TestCompletionCallback callback;
5744
bnc87dcefc2017-05-25 12:47:585745 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195746 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205747 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225749
5750 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015751 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225752
5753 LoadTimingInfo load_timing_info;
5754 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5755 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5756
5757 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525758 ASSERT_TRUE(response);
5759 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225760 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5761
5762 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295763 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505764 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225765 trans.reset();
5766
bnc87dcefc2017-05-25 12:47:585767 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195768 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205769 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225771
[email protected]f6c63db52013-02-02 00:35:225772 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015773 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225774
5775 LoadTimingInfo load_timing_info2;
5776 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5777 TestLoadTimingReused(load_timing_info2);
5778
5779 // The requests should have the same ID.
5780 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5781
[email protected]90499482013-06-01 00:39:505782 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225783}
5784
5785// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5786// Proxy to different servers.
bncd16676a2016-07-20 16:23:015787TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225788 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495789 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5790 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515791 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075792 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095793 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505794 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225795
5796 HttpRequestInfo request1;
5797 request1.method = "GET";
bncce36dca22015-04-21 22:11:235798 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225799 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105800 request1.traffic_annotation =
5801 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225802
5803 HttpRequestInfo request2;
5804 request2.method = "GET";
bncce36dca22015-04-21 22:11:235805 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225806 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105807 request2.traffic_annotation =
5808 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225809
bncce36dca22015-04-21 22:11:235810 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265811 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235812 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415813 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155814 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5815 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Bence Békyd74f4382018-02-20 18:26:195816 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385817 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225818
bncce36dca22015-04-21 22:11:235819 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265820 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235821 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415822 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155823 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5824 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
Bence Békyd74f4382018-02-20 18:26:195825 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225826
5827 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415828 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225829 };
5830
5831 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415832 CreateMockRead(get_resp1, 1, ASYNC),
5833 CreateMockRead(body1, 2, ASYNC),
5834 CreateMockRead(get_resp2, 4, ASYNC),
5835 CreateMockRead(body2, 5, ASYNC),
5836 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225837 };
5838
mmenke11eb5152015-06-09 14:50:505839 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5840 arraysize(spdy_writes));
5841 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225842
5843 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365844 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225846
5847 TestCompletionCallback callback;
5848
bnc87dcefc2017-05-25 12:47:585849 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195850 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205851 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015852 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225853
5854 LoadTimingInfo load_timing_info;
5855 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5856 TestLoadTimingNotReused(load_timing_info,
5857 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5858
5859 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525860 ASSERT_TRUE(response);
5861 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025862 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225863
5864 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295865 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505866 rv = trans->Read(buf.get(), 256, callback.callback());
5867 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225868 // Delete the first request, so the second one can reuse the socket.
5869 trans.reset();
5870
bnc691fda62016-08-12 00:43:165871 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205872 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015873 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225874
5875 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165876 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225877 TestLoadTimingReused(load_timing_info2);
5878
5879 // The requests should have the same ID.
5880 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5881
bnc691fda62016-08-12 00:43:165882 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505883 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225884}
5885
[email protected]2df19bb2010-08-25 20:13:465886// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015887TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465888 HttpRequestInfo request;
5889 request.method = "GET";
bncce36dca22015-04-21 22:11:235890 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465891 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295892 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:105893 request.traffic_annotation =
5894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465895
[email protected]79cb5c12011-09-12 13:12:045896 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495897 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5898 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515899 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075900 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095901 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275902
[email protected]2df19bb2010-08-25 20:13:465903 // Since we have proxy, should use full url
5904 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165905 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5906 "Host: www.example.org\r\n"
5907 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465908
bnc691fda62016-08-12 00:43:165909 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235910 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165911 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5912 "Host: www.example.org\r\n"
5913 "Proxy-Connection: keep-alive\r\n"
5914 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465915 };
5916
5917 // The proxy responds to the GET with a 407, using a persistent
5918 // connection.
5919 MockRead data_reads1[] = {
5920 // No credentials.
5921 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5922 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5923 MockRead("Proxy-Connection: keep-alive\r\n"),
5924 MockRead("Content-Length: 0\r\n\r\n"),
5925
5926 MockRead("HTTP/1.1 200 OK\r\n"),
5927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5928 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065929 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465930 };
5931
5932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5933 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075934 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065935 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075936 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465937
[email protected]49639fa2011-12-20 23:22:415938 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465939
bnc691fda62016-08-12 00:43:165940 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505941
bnc691fda62016-08-12 00:43:165942 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465944
5945 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015946 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465947
[email protected]58e32bb2013-01-21 18:23:255948 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165949 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255950 TestLoadTimingNotReused(load_timing_info,
5951 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5952
bnc691fda62016-08-12 00:43:165953 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525954 ASSERT_TRUE(response);
5955 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465956 EXPECT_EQ(407, response->headers->response_code());
5957 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435958 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465959
[email protected]49639fa2011-12-20 23:22:415960 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465961
bnc691fda62016-08-12 00:43:165962 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465964
5965 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015966 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465967
[email protected]58e32bb2013-01-21 18:23:255968 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165969 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255970 // Retrying with HTTP AUTH is considered to be reusing a socket.
5971 TestLoadTimingReused(load_timing_info);
5972
bnc691fda62016-08-12 00:43:165973 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525974 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465975
5976 EXPECT_TRUE(response->headers->IsKeepAlive());
5977 EXPECT_EQ(200, response->headers->response_code());
5978 EXPECT_EQ(100, response->headers->GetContentLength());
5979 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5980
5981 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525982 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465983}
5984
[email protected]23e482282013-06-14 16:08:025985void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085986 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425987 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085988 request.method = "GET";
bncce36dca22015-04-21 22:11:235989 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105990 request.traffic_annotation =
5991 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:085992
[email protected]cb9bf6ca2011-01-28 13:15:275993 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495994 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5995 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:095996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275997
[email protected]c744cf22009-02-27 07:28:085998 // Since we have proxy, should try to establish tunnel.
5999 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176000 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6001 "Host: www.example.org:443\r\n"
6002 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086003 };
6004
6005 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236006 status, MockRead("Content-Length: 10\r\n\r\n"),
6007 // No response body because the test stops reading here.
6008 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086009 };
6010
[email protected]31a2bfe2010-02-09 08:03:396011 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6012 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076013 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086014
[email protected]49639fa2011-12-20 23:22:416015 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086016
bnc691fda62016-08-12 00:43:166017 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506018
tfarina42834112016-09-22 13:38:206019 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086021
6022 rv = callback.WaitForResult();
6023 EXPECT_EQ(expected_status, rv);
6024}
6025
[email protected]23e482282013-06-14 16:08:026026void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236027 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086028 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426029 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086030}
6031
bncd16676a2016-07-20 16:23:016032TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086033 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6034}
6035
bncd16676a2016-07-20 16:23:016036TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086037 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6038}
6039
bncd16676a2016-07-20 16:23:016040TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086041 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6042}
6043
bncd16676a2016-07-20 16:23:016044TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086045 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6046}
6047
bncd16676a2016-07-20 16:23:016048TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086049 ConnectStatusHelper(
6050 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6051}
6052
bncd16676a2016-07-20 16:23:016053TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086054 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6055}
6056
bncd16676a2016-07-20 16:23:016057TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086058 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6059}
6060
bncd16676a2016-07-20 16:23:016061TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086062 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6063}
6064
bncd16676a2016-07-20 16:23:016065TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086066 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6067}
6068
bncd16676a2016-07-20 16:23:016069TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086070 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6071}
6072
bncd16676a2016-07-20 16:23:016073TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086074 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6075}
6076
bncd16676a2016-07-20 16:23:016077TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086078 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6079}
6080
bncd16676a2016-07-20 16:23:016081TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086082 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6083}
6084
bncd16676a2016-07-20 16:23:016085TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086086 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6087}
6088
bncd16676a2016-07-20 16:23:016089TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086090 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6091}
6092
bncd16676a2016-07-20 16:23:016093TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086094 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6095}
6096
bncd16676a2016-07-20 16:23:016097TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376098 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6099}
6100
bncd16676a2016-07-20 16:23:016101TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086102 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6103}
6104
bncd16676a2016-07-20 16:23:016105TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086106 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6107}
6108
bncd16676a2016-07-20 16:23:016109TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086110 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6111}
6112
bncd16676a2016-07-20 16:23:016113TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086114 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6115}
6116
bncd16676a2016-07-20 16:23:016117TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086118 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6119}
6120
bncd16676a2016-07-20 16:23:016121TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086122 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6123}
6124
bncd16676a2016-07-20 16:23:016125TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086126 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6127}
6128
bncd16676a2016-07-20 16:23:016129TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086130 ConnectStatusHelperWithExpectedStatus(
6131 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546132 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086133}
6134
bncd16676a2016-07-20 16:23:016135TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086136 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6137}
6138
bncd16676a2016-07-20 16:23:016139TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086140 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6141}
6142
bncd16676a2016-07-20 16:23:016143TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086144 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6145}
6146
bncd16676a2016-07-20 16:23:016147TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086148 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6149}
6150
bncd16676a2016-07-20 16:23:016151TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086152 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6153}
6154
bncd16676a2016-07-20 16:23:016155TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086156 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6157}
6158
bncd16676a2016-07-20 16:23:016159TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086160 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6161}
6162
bncd16676a2016-07-20 16:23:016163TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086164 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6165}
6166
bncd16676a2016-07-20 16:23:016167TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086168 ConnectStatusHelper(
6169 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6170}
6171
bncd16676a2016-07-20 16:23:016172TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086173 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6174}
6175
bncd16676a2016-07-20 16:23:016176TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086177 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6178}
6179
bncd16676a2016-07-20 16:23:016180TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086181 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6182}
6183
bncd16676a2016-07-20 16:23:016184TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086185 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6186}
6187
bncd16676a2016-07-20 16:23:016188TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086189 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6190}
6191
bncd16676a2016-07-20 16:23:016192TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086193 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6194}
6195
bncd16676a2016-07-20 16:23:016196TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086197 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6198}
6199
[email protected]038e9a32008-10-08 22:40:166200// Test the flow when both the proxy server AND origin server require
6201// authentication. Again, this uses basic auth for both since that is
6202// the simplest to mock.
bncd16676a2016-07-20 16:23:016203TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276204 HttpRequestInfo request;
6205 request.method = "GET";
bncce36dca22015-04-21 22:11:236206 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106207 request.traffic_annotation =
6208 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276209
[email protected]038e9a32008-10-08 22:40:166210 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496211 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6212 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096213 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076214
bnc691fda62016-08-12 00:43:166215 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166216
[email protected]f9ee6b52008-11-08 06:46:236217 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236218 MockWrite(
6219 "GET http://www.example.org/ HTTP/1.1\r\n"
6220 "Host: www.example.org\r\n"
6221 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236222 };
6223
[email protected]038e9a32008-10-08 22:40:166224 MockRead data_reads1[] = {
6225 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6226 // Give a couple authenticate options (only the middle one is actually
6227 // supported).
[email protected]22927ad2009-09-21 19:56:196228 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166229 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6230 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6231 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6232 // Large content-length -- won't matter, as connection will be reset.
6233 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066234 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166235 };
6236
bnc691fda62016-08-12 00:43:166237 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166238 // request we should be issuing -- the final header line contains the
6239 // proxy's credentials.
6240 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236241 MockWrite(
6242 "GET http://www.example.org/ HTTP/1.1\r\n"
6243 "Host: www.example.org\r\n"
6244 "Proxy-Connection: keep-alive\r\n"
6245 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166246 };
6247
6248 // Now the proxy server lets the request pass through to origin server.
6249 // The origin server responds with a 401.
6250 MockRead data_reads2[] = {
6251 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6252 // Note: We are using the same realm-name as the proxy server. This is
6253 // completely valid, as realms are unique across hosts.
6254 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6255 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6256 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066257 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166258 };
6259
bnc691fda62016-08-12 00:43:166260 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166261 // the credentials for both the proxy and origin server.
6262 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236263 MockWrite(
6264 "GET http://www.example.org/ HTTP/1.1\r\n"
6265 "Host: www.example.org\r\n"
6266 "Proxy-Connection: keep-alive\r\n"
6267 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6268 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166269 };
6270
6271 // Lastly we get the desired content.
6272 MockRead data_reads3[] = {
6273 MockRead("HTTP/1.0 200 OK\r\n"),
6274 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6275 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066276 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166277 };
6278
[email protected]31a2bfe2010-02-09 08:03:396279 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6280 data_writes1, arraysize(data_writes1));
6281 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6282 data_writes2, arraysize(data_writes2));
6283 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6284 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076285 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6286 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6287 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166288
[email protected]49639fa2011-12-20 23:22:416289 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166290
tfarina42834112016-09-22 13:38:206291 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166293
6294 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016295 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166296
bnc691fda62016-08-12 00:43:166297 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526298 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046299 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166300
[email protected]49639fa2011-12-20 23:22:416301 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166302
bnc691fda62016-08-12 00:43:166303 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166305
6306 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016307 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166308
bnc691fda62016-08-12 00:43:166309 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526310 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046311 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166312
[email protected]49639fa2011-12-20 23:22:416313 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166314
bnc691fda62016-08-12 00:43:166315 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6316 callback3.callback());
robpercival214763f2016-07-01 23:27:016317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166318
6319 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016320 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166321
bnc691fda62016-08-12 00:43:166322 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526323 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166324 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166325}
[email protected]4ddaf2502008-10-23 18:26:196326
[email protected]ea9dc9a2009-09-05 00:43:326327// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6328// can't hook into its internals to cause it to generate predictable NTLM
6329// authorization headers.
6330#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376331// The NTLM authentication unit tests are based on known test data from the
6332// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6333// flow rather than the implementation of the NTLM protocol. See net/ntlm
6334// for the implementation and testing of the protocol.
6335//
6336// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296337
6338// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556339TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426340 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246341 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556342 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106343 request.traffic_annotation =
6344 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546345
6346 // Ensure load is not disrupted by flags which suppress behaviour specific
6347 // to other auth schemes.
6348 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246349
Zentaro Kavanagh6ccee512017-09-28 18:34:096350 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6351 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276353
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376354 // Generate the NTLM messages based on known test data.
6355 std::string negotiate_msg;
6356 std::string challenge_msg;
6357 std::string authenticate_msg;
6358 base::Base64Encode(
6359 base::StringPiece(
6360 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6361 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6362 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556363 base::Base64Encode(
6364 base::StringPiece(
6365 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6366 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6367 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376368 base::Base64Encode(
6369 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096370 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556371 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6372 arraysize(
6373 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376374 &authenticate_msg);
6375
[email protected]3f918782009-02-28 01:29:246376 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556377 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6378 "Host: server\r\n"
6379 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246380 };
6381
6382 MockRead data_reads1[] = {
6383 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046384 // Negotiate and NTLM are often requested together. However, we only want
6385 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6386 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246387 MockRead("WWW-Authenticate: NTLM\r\n"),
6388 MockRead("Connection: close\r\n"),
6389 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366390 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246391 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246392 };
6393
6394 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166395 // After restarting with a null identity, this is the
6396 // request we should be issuing -- the final header line contains a Type
6397 // 1 message.
6398 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556399 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166400 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376401 "Authorization: NTLM "),
6402 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246403
bnc691fda62016-08-12 00:43:166404 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376405 // (using correct credentials). The second request continues on the
6406 // same connection.
bnc691fda62016-08-12 00:43:166407 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556408 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166409 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376410 "Authorization: NTLM "),
6411 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246412 };
6413
6414 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026415 // The origin server responds with a Type 2 message.
6416 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376417 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6418 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026419 MockRead("Content-Type: text/html\r\n\r\n"),
6420 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246421
Bence Béky1e4ef192017-09-18 19:58:026422 // Lastly we get the desired content.
6423 MockRead("HTTP/1.1 200 OK\r\n"),
6424 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6425 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246426 };
6427
[email protected]31a2bfe2010-02-09 08:03:396428 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6429 data_writes1, arraysize(data_writes1));
6430 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6431 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076432 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6433 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246434
Bence Béky83eb3512017-09-05 12:56:096435 SSLSocketDataProvider ssl1(ASYNC, OK);
6436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6437 SSLSocketDataProvider ssl2(ASYNC, OK);
6438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6439
[email protected]49639fa2011-12-20 23:22:416440 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246441
bnc691fda62016-08-12 00:43:166442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506443
tfarina42834112016-09-22 13:38:206444 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246446
6447 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016448 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246449
bnc691fda62016-08-12 00:43:166450 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226451
bnc691fda62016-08-12 00:43:166452 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526453 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046454 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246455
[email protected]49639fa2011-12-20 23:22:416456 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256457
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376458 rv = trans.RestartWithAuth(
6459 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6460 callback2.callback());
robpercival214763f2016-07-01 23:27:016461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256462
6463 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016464 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256465
bnc691fda62016-08-12 00:43:166466 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256467
bnc691fda62016-08-12 00:43:166468 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526469 ASSERT_TRUE(response);
6470 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256471
[email protected]49639fa2011-12-20 23:22:416472 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246473
bnc691fda62016-08-12 00:43:166474 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246476
[email protected]0757e7702009-03-27 04:00:226477 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016478 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246479
bnc691fda62016-08-12 00:43:166480 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526481 ASSERT_TRUE(response);
6482 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026483 EXPECT_EQ(14, response->headers->GetContentLength());
6484
6485 std::string response_data;
6486 rv = ReadTransaction(&trans, &response_data);
6487 EXPECT_THAT(rv, IsOk());
6488 EXPECT_EQ("Please Login\r\n", response_data);
6489
6490 EXPECT_TRUE(data1.AllReadDataConsumed());
6491 EXPECT_TRUE(data1.AllWriteDataConsumed());
6492 EXPECT_TRUE(data2.AllReadDataConsumed());
6493 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246494}
6495
[email protected]385a4672009-03-11 22:21:296496// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556497TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426498 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296499 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556500 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106501 request.traffic_annotation =
6502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296503
Zentaro Kavanagh6ccee512017-09-28 18:34:096504 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6505 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276507
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376508 // Generate the NTLM messages based on known test data.
6509 std::string negotiate_msg;
6510 std::string challenge_msg;
6511 std::string authenticate_msg;
6512 base::Base64Encode(
6513 base::StringPiece(
6514 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6515 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6516 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556517 base::Base64Encode(
6518 base::StringPiece(
6519 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6520 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6521 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376522 base::Base64Encode(
6523 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096524 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556525 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6526 arraysize(
6527 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376528 &authenticate_msg);
6529
6530 // The authenticate message when |kWrongPassword| is sent.
6531 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556532 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6533 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6534 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6535 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6536 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6537 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376538
Zentaro Kavanagh1890a3d2018-01-29 19:52:556539 // Sanity check that it's the same length as the correct authenticate message
6540 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376541 ASSERT_EQ(authenticate_msg.length(),
6542 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556543 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376544
[email protected]385a4672009-03-11 22:21:296545 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556546 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6547 "Host: server\r\n"
6548 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296549 };
6550
6551 MockRead data_reads1[] = {
6552 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046553 // Negotiate and NTLM are often requested together. However, we only want
6554 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6555 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296556 MockRead("WWW-Authenticate: NTLM\r\n"),
6557 MockRead("Connection: close\r\n"),
6558 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366559 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296560 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296561 };
6562
6563 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166564 // After restarting with a null identity, this is the
6565 // request we should be issuing -- the final header line contains a Type
6566 // 1 message.
6567 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556568 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166569 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376570 "Authorization: NTLM "),
6571 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296572
bnc691fda62016-08-12 00:43:166573 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376574 // (using incorrect credentials). The second request continues on the
6575 // same connection.
bnc691fda62016-08-12 00:43:166576 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556577 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166578 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376579 "Authorization: NTLM "),
6580 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296581 };
6582
6583 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376584 // The origin server responds with a Type 2 message.
6585 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6586 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6587 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6588 MockRead("Content-Type: text/html\r\n\r\n"),
6589 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296590
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376591 // Wrong password.
6592 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6593 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6594 MockRead("Content-Length: 42\r\n"),
6595 MockRead("Content-Type: text/html\r\n\r\n"),
6596 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296597 };
6598
6599 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166600 // After restarting with a null identity, this is the
6601 // request we should be issuing -- the final header line contains a Type
6602 // 1 message.
6603 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556604 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166605 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376606 "Authorization: NTLM "),
6607 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296608
bnc691fda62016-08-12 00:43:166609 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6610 // (the credentials for the origin server). The second request continues
6611 // on the same connection.
6612 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556613 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166614 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376615 "Authorization: NTLM "),
6616 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296617 };
6618
6619 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026620 // The origin server responds with a Type 2 message.
6621 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376622 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6623 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026624 MockRead("Content-Type: text/html\r\n\r\n"),
6625 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296626
Bence Béky1e4ef192017-09-18 19:58:026627 // Lastly we get the desired content.
6628 MockRead("HTTP/1.1 200 OK\r\n"),
6629 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6630 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296631 };
6632
[email protected]31a2bfe2010-02-09 08:03:396633 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6634 data_writes1, arraysize(data_writes1));
6635 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6636 data_writes2, arraysize(data_writes2));
6637 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6638 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076639 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6640 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6641 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296642
Bence Béky83eb3512017-09-05 12:56:096643 SSLSocketDataProvider ssl1(ASYNC, OK);
6644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6645 SSLSocketDataProvider ssl2(ASYNC, OK);
6646 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6647 SSLSocketDataProvider ssl3(ASYNC, OK);
6648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6649
[email protected]49639fa2011-12-20 23:22:416650 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296651
bnc691fda62016-08-12 00:43:166652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506653
tfarina42834112016-09-22 13:38:206654 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296656
6657 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016658 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296659
bnc691fda62016-08-12 00:43:166660 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296661
bnc691fda62016-08-12 00:43:166662 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526663 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046664 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296665
[email protected]49639fa2011-12-20 23:22:416666 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296667
[email protected]0757e7702009-03-27 04:00:226668 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376669 rv = trans.RestartWithAuth(
6670 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6671 callback2.callback());
robpercival214763f2016-07-01 23:27:016672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296673
[email protected]10af5fe72011-01-31 16:17:256674 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016675 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296676
bnc691fda62016-08-12 00:43:166677 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416678 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166679 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256681 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016682 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166683 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226684
bnc691fda62016-08-12 00:43:166685 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526686 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046687 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226688
[email protected]49639fa2011-12-20 23:22:416689 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226690
6691 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376692 rv = trans.RestartWithAuth(
6693 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6694 callback4.callback());
robpercival214763f2016-07-01 23:27:016695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256696
6697 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016698 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256699
bnc691fda62016-08-12 00:43:166700 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256701
[email protected]49639fa2011-12-20 23:22:416702 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256703
6704 // One more roundtrip
bnc691fda62016-08-12 00:43:166705 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226707
6708 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016709 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226710
bnc691fda62016-08-12 00:43:166711 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526712 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026713 EXPECT_EQ(14, response->headers->GetContentLength());
6714
6715 std::string response_data;
6716 rv = ReadTransaction(&trans, &response_data);
6717 EXPECT_THAT(rv, IsOk());
6718 EXPECT_EQ("Please Login\r\n", response_data);
6719
6720 EXPECT_TRUE(data1.AllReadDataConsumed());
6721 EXPECT_TRUE(data1.AllWriteDataConsumed());
6722 EXPECT_TRUE(data2.AllReadDataConsumed());
6723 EXPECT_TRUE(data2.AllWriteDataConsumed());
6724 EXPECT_TRUE(data3.AllReadDataConsumed());
6725 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296726}
Bence Béky83eb3512017-09-05 12:56:096727
Bence Béky3238f2e12017-09-22 22:44:496728// Server requests NTLM authentication, which is not supported over HTTP/2.
6729// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096730TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096731 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6732 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096733
Zentaro Kavanagh1890a3d2018-01-29 19:52:556734 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096735
6736 HttpRequestInfo request;
6737 request.method = "GET";
6738 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:106739 request.traffic_annotation =
6740 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096741
6742 // First request without credentials.
6743 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6744 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6745 1, std::move(request_headers0), LOWEST, true));
6746
6747 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276748 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096749 response_headers0["www-authenticate"] = "NTLM";
6750 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6751 1, std::move(response_headers0), true));
6752
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376753 // Stream 1 is closed.
6754 spdy_util_.UpdateWithStreamDestruction(1);
6755
6756 // Generate the NTLM messages based on known test data.
6757 std::string negotiate_msg;
6758 std::string challenge_msg;
6759 std::string authenticate_msg;
6760 base::Base64Encode(
6761 base::StringPiece(
6762 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6763 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6764 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556765 base::Base64Encode(
6766 base::StringPiece(
6767 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6768 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6769 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376770 base::Base64Encode(
6771 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096772 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556773 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6774 arraysize(
6775 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376776 &authenticate_msg);
6777
6778 // Retry with authorization header.
6779 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6780 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6781 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6782 3, std::move(request_headers1), LOWEST, true));
6783
6784 SpdySerializedFrame rst(
6785 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6786
Bence Béky3238f2e12017-09-22 22:44:496787 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6788 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096789
6790 // Retry yet again using HTTP/1.1.
6791 MockWrite writes1[] = {
6792 // After restarting with a null identity, this is the
6793 // request we should be issuing -- the final header line contains a Type
6794 // 1 message.
6795 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556796 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096797 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376798 "Authorization: NTLM "),
6799 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096800
6801 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6802 // (the credentials for the origin server). The second request continues
6803 // on the same connection.
6804 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556805 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096806 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376807 "Authorization: NTLM "),
6808 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096809 };
6810
6811 MockRead reads1[] = {
6812 // The origin server responds with a Type 2 message.
6813 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376814 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6815 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096816 MockRead("Content-Type: text/html\r\n\r\n"),
6817 MockRead("You are not authorized to view this page\r\n"),
6818
6819 // Lastly we get the desired content.
6820 MockRead("HTTP/1.1 200 OK\r\n"),
6821 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026822 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096823 };
6824 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6825 arraysize(writes0));
6826 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6827 arraysize(writes1));
6828 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6829 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6830
6831 SSLSocketDataProvider ssl0(ASYNC, OK);
6832 ssl0.next_proto = kProtoHTTP2;
6833 SSLSocketDataProvider ssl1(ASYNC, OK);
6834 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6835 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6836
6837 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6838 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6839
6840 TestCompletionCallback callback1;
6841 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6843
6844 rv = callback1.WaitForResult();
6845 EXPECT_THAT(rv, IsOk());
6846
6847 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6848
6849 const HttpResponseInfo* response = trans.GetResponseInfo();
6850 ASSERT_TRUE(response);
6851 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6852
6853 TestCompletionCallback callback2;
6854
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376855 rv = trans.RestartWithAuth(
6856 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6857 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6859
6860 rv = callback2.WaitForResult();
6861 EXPECT_THAT(rv, IsOk());
6862
6863 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6864
6865 response = trans.GetResponseInfo();
6866 ASSERT_TRUE(response);
6867 EXPECT_FALSE(response->auth_challenge);
6868
6869 TestCompletionCallback callback3;
6870
6871 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6873
6874 rv = callback3.WaitForResult();
6875 EXPECT_THAT(rv, IsOk());
6876
6877 response = trans.GetResponseInfo();
6878 ASSERT_TRUE(response);
6879 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026880 EXPECT_EQ(14, response->headers->GetContentLength());
6881
6882 std::string response_data;
6883 rv = ReadTransaction(&trans, &response_data);
6884 EXPECT_THAT(rv, IsOk());
6885 EXPECT_EQ("Please Login\r\n", response_data);
6886
6887 EXPECT_TRUE(data0.AllReadDataConsumed());
6888 EXPECT_TRUE(data0.AllWriteDataConsumed());
6889 EXPECT_TRUE(data1.AllReadDataConsumed());
6890 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096891}
David Benjamin5cb91132018-04-06 05:54:496892
6893// Test that, if we have an NTLM proxy and the origin resets the connection, we
6894// do no retry forever checking for TLS version interference. This is a
6895// regression test for https://crbug.com/823387.
6896TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
6897 // The NTLM test data expects the proxy to be named 'server'. The origin is
6898 // https://origin/.
6899 session_deps_.proxy_resolution_service =
6900 ProxyResolutionService::CreateFixedFromPacResult(
6901 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
6902
6903 SSLConfig config;
6904 config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
6905 session_deps_.ssl_config_service =
6906 base::MakeRefCounted<TestSSLConfigService>(config);
6907
6908 HttpRequestInfo request;
6909 request.method = "GET";
6910 request.url = GURL("https://origin/");
6911 request.traffic_annotation =
6912 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6913
6914 // Ensure load is not disrupted by flags which suppress behaviour specific
6915 // to other auth schemes.
6916 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6917
6918 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6919 MockGetMSTime, MockGenerateRandom, MockGetHostName);
6920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6921
6922 // Generate the NTLM messages based on known test data.
6923 std::string negotiate_msg;
6924 std::string challenge_msg;
6925 std::string authenticate_msg;
6926 base::Base64Encode(
6927 base::StringPiece(
6928 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6929 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6930 &negotiate_msg);
6931 base::Base64Encode(
6932 base::StringPiece(
6933 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6934 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6935 &challenge_msg);
6936 base::Base64Encode(
6937 base::StringPiece(
6938 reinterpret_cast<const char*>(
6939 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6940 arraysize(
6941 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
6942 &authenticate_msg);
6943
6944 MockWrite data_writes[] = {
6945 // The initial CONNECT request.
6946 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6947 "Host: origin:443\r\n"
6948 "Proxy-Connection: keep-alive\r\n\r\n"),
6949
6950 // After restarting with an identity.
6951 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6952 "Host: origin:443\r\n"
6953 "Proxy-Connection: keep-alive\r\n"
6954 "Proxy-Authorization: NTLM "),
6955 MockWrite(negotiate_msg.c_str()),
6956 // End headers.
6957 MockWrite("\r\n\r\n"),
6958
6959 // The second restart.
6960 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6961 "Host: origin:443\r\n"
6962 "Proxy-Connection: keep-alive\r\n"
6963 "Proxy-Authorization: NTLM "),
6964 MockWrite(authenticate_msg.c_str()),
6965 // End headers.
6966 MockWrite("\r\n\r\n"),
6967 };
6968
6969 MockRead data_reads[] = {
6970 // The initial NTLM response.
6971 MockRead("HTTP/1.1 407 Access Denied\r\n"
6972 "Content-Length: 0\r\n"
6973 "Proxy-Authenticate: NTLM\r\n\r\n"),
6974
6975 // The NTLM challenge message.
6976 MockRead("HTTP/1.1 407 Access Denied\r\n"
6977 "Content-Length: 0\r\n"
6978 "Proxy-Authenticate: NTLM "),
6979 MockRead(challenge_msg.c_str()),
6980 // End headers.
6981 MockRead("\r\n\r\n"),
6982
6983 // Finally the tunnel is established.
6984 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
6985 };
6986
6987 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6988 arraysize(data_writes));
6989 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
6990 StaticSocketDataProvider data2(data_reads, arraysize(data_reads), data_writes,
6991 arraysize(data_writes));
6992 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
6993 session_deps_.socket_factory->AddSocketDataProvider(&data);
6994 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
6995 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6996 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
6997
6998 // Start the transaction. The proxy responds with an NTLM authentication
6999 // request.
7000 TestCompletionCallback callback;
7001 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7002 int rv = callback.GetResult(
7003 trans.Start(&request, callback.callback(), NetLogWithSource()));
7004
7005 EXPECT_THAT(rv, IsOk());
7006 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7007 const HttpResponseInfo* response = trans.GetResponseInfo();
7008 ASSERT_TRUE(response);
7009 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7010
7011 // Configure credentials. The proxy responds with the challenge message.
7012 rv = callback.GetResult(trans.RestartWithAuth(
7013 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7014 callback.callback()));
7015 EXPECT_THAT(rv, IsOk());
7016 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7017 response = trans.GetResponseInfo();
7018 ASSERT_TRUE(response);
7019 EXPECT_FALSE(response->auth_challenge);
7020
7021 // Restart once more. The tunnel will be established and the the SSL handshake
7022 // will reset. The TLS 1.3 version interference probe will then kick in and
7023 // restart the process. The proxy responds with another NTLM authentiation
7024 // request, but we don't need to provide credentials as the cached ones work/
7025 rv = callback.GetResult(
7026 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7027 EXPECT_THAT(rv, IsOk());
7028 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7029 response = trans.GetResponseInfo();
7030 ASSERT_TRUE(response);
7031 EXPECT_FALSE(response->auth_challenge);
7032
7033 // The proxy responds with the NTLM challenge message.
7034 rv = callback.GetResult(
7035 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7036 EXPECT_THAT(rv, IsOk());
7037 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7038 response = trans.GetResponseInfo();
7039 ASSERT_TRUE(response);
7040 EXPECT_FALSE(response->auth_challenge);
7041
7042 // Send the NTLM authenticate message. The tunnel is established and the
7043 // handshake resets again. We should not retry again.
7044 rv = callback.GetResult(
7045 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7046 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7047}
7048
[email protected]ea9dc9a2009-09-05 00:43:327049#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297050
[email protected]4ddaf2502008-10-23 18:26:197051// Test reading a server response which has only headers, and no body.
7052// After some maximum number of bytes is consumed, the transaction should
7053// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017054TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427055 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197056 request.method = "GET";
bncce36dca22015-04-21 22:11:237057 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107058 request.traffic_annotation =
7059 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197060
danakj1fd259a02016-04-16 03:17:097061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167062 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277063
[email protected]b75b7b2f2009-10-06 00:54:537064 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437065 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537066 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197067
7068 MockRead data_reads[] = {
7069 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067070 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197071 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067072 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197073 };
[email protected]31a2bfe2010-02-09 08:03:397074 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077075 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197076
[email protected]49639fa2011-12-20 23:22:417077 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197078
tfarina42834112016-09-22 13:38:207079 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197081
7082 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017083 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197084}
[email protected]f4e426b2008-11-05 00:24:497085
7086// Make sure that we don't try to reuse a TCPClientSocket when failing to
7087// establish tunnel.
7088// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017089TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277090 HttpRequestInfo request;
7091 request.method = "GET";
bncce36dca22015-04-21 22:11:237092 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107093 request.traffic_annotation =
7094 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277095
[email protected]f4e426b2008-11-05 00:24:497096 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497097 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7098 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017099
danakj1fd259a02016-04-16 03:17:097100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497101
bnc87dcefc2017-05-25 12:47:587102 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197103 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497104
[email protected]f4e426b2008-11-05 00:24:497105 // Since we have proxy, should try to establish tunnel.
7106 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177107 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7108 "Host: www.example.org:443\r\n"
7109 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497110 };
7111
[email protected]77848d12008-11-14 00:00:227112 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497113 // connection. Usually a proxy would return 501 (not implemented),
7114 // or 200 (tunnel established).
7115 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237116 MockRead("HTTP/1.1 404 Not Found\r\n"),
7117 MockRead("Content-Length: 10\r\n\r\n"),
7118 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497119 };
7120
[email protected]31a2bfe2010-02-09 08:03:397121 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7122 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497124
[email protected]49639fa2011-12-20 23:22:417125 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497126
tfarina42834112016-09-22 13:38:207127 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497129
7130 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017131 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497132
[email protected]b4404c02009-04-10 16:38:527133 // Empty the current queue. This is necessary because idle sockets are
7134 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557135 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527136
[email protected]f4e426b2008-11-05 00:24:497137 // We now check to make sure the TCPClientSocket was not added back to
7138 // the pool.
[email protected]90499482013-06-01 00:39:507139 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497140 trans.reset();
fdoray92e35a72016-06-10 15:54:557141 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497142 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507143 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497144}
[email protected]372d34a2008-11-05 21:30:517145
[email protected]1b157c02009-04-21 01:55:407146// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017147TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427148 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407149 request.method = "GET";
bncce36dca22015-04-21 22:11:237150 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107151 request.traffic_annotation =
7152 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407153
danakj1fd259a02016-04-16 03:17:097154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277155
bnc691fda62016-08-12 00:43:167156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277157
[email protected]1b157c02009-04-21 01:55:407158 MockRead data_reads[] = {
7159 // A part of the response body is received with the response headers.
7160 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7161 // The rest of the response body is received in two parts.
7162 MockRead("lo"),
7163 MockRead(" world"),
7164 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067165 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407166 };
7167
[email protected]31a2bfe2010-02-09 08:03:397168 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077169 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407170
[email protected]49639fa2011-12-20 23:22:417171 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407172
tfarina42834112016-09-22 13:38:207173 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407175
7176 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017177 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407178
bnc691fda62016-08-12 00:43:167179 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527180 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407181
wezca1070932016-05-26 20:30:527182 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407183 std::string status_line = response->headers->GetStatusLine();
7184 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7185
[email protected]90499482013-06-01 00:39:507186 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407187
7188 std::string response_data;
bnc691fda62016-08-12 00:43:167189 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017190 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407191 EXPECT_EQ("hello world", response_data);
7192
7193 // Empty the current queue. This is necessary because idle sockets are
7194 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557195 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407196
7197 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507198 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407199}
7200
[email protected]76a505b2010-08-25 06:23:007201// Make sure that we recycle a SSL socket after reading all of the response
7202// body.
bncd16676a2016-07-20 16:23:017203TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007204 HttpRequestInfo request;
7205 request.method = "GET";
bncce36dca22015-04-21 22:11:237206 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107207 request.traffic_annotation =
7208 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007209
7210 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237211 MockWrite(
7212 "GET / HTTP/1.1\r\n"
7213 "Host: www.example.org\r\n"
7214 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007215 };
7216
7217 MockRead data_reads[] = {
7218 MockRead("HTTP/1.1 200 OK\r\n"),
7219 MockRead("Content-Length: 11\r\n\r\n"),
7220 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067221 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007222 };
7223
[email protected]8ddf8322012-02-23 18:08:067224 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007226
7227 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7228 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077229 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007230
[email protected]49639fa2011-12-20 23:22:417231 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007232
danakj1fd259a02016-04-16 03:17:097233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007235
tfarina42834112016-09-22 13:38:207236 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007237
robpercival214763f2016-07-01 23:27:017238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7239 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007240
bnc691fda62016-08-12 00:43:167241 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527242 ASSERT_TRUE(response);
7243 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007244 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7245
[email protected]90499482013-06-01 00:39:507246 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007247
7248 std::string response_data;
bnc691fda62016-08-12 00:43:167249 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017250 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007251 EXPECT_EQ("hello world", response_data);
7252
7253 // Empty the current queue. This is necessary because idle sockets are
7254 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557255 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007256
7257 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507258 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007259}
7260
7261// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7262// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017263TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007264 HttpRequestInfo request;
7265 request.method = "GET";
bncce36dca22015-04-21 22:11:237266 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107267 request.traffic_annotation =
7268 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007269
7270 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237271 MockWrite(
7272 "GET / HTTP/1.1\r\n"
7273 "Host: www.example.org\r\n"
7274 "Connection: keep-alive\r\n\r\n"),
7275 MockWrite(
7276 "GET / HTTP/1.1\r\n"
7277 "Host: www.example.org\r\n"
7278 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007279 };
7280
7281 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427282 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7283 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007284
[email protected]8ddf8322012-02-23 18:08:067285 SSLSocketDataProvider ssl(ASYNC, OK);
7286 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077287 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007289
7290 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7291 data_writes, arraysize(data_writes));
7292 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7293 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077294 session_deps_.socket_factory->AddSocketDataProvider(&data);
7295 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007296
[email protected]49639fa2011-12-20 23:22:417297 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007298
danakj1fd259a02016-04-16 03:17:097299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587300 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197301 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007302
tfarina42834112016-09-22 13:38:207303 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007304
robpercival214763f2016-07-01 23:27:017305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7306 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007307
7308 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527309 ASSERT_TRUE(response);
7310 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007311 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7312
[email protected]90499482013-06-01 00:39:507313 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007314
7315 std::string response_data;
7316 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017317 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007318 EXPECT_EQ("hello world", response_data);
7319
7320 // Empty the current queue. This is necessary because idle sockets are
7321 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557322 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007323
7324 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507325 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007326
7327 // Now start the second transaction, which should reuse the previous socket.
7328
bnc87dcefc2017-05-25 12:47:587329 trans =
Jeremy Roman0579ed62017-08-29 15:56:197330 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007331
tfarina42834112016-09-22 13:38:207332 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007333
robpercival214763f2016-07-01 23:27:017334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7335 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007336
7337 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527338 ASSERT_TRUE(response);
7339 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007340 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7341
[email protected]90499482013-06-01 00:39:507342 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007343
7344 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017345 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007346 EXPECT_EQ("hello world", response_data);
7347
7348 // Empty the current queue. This is necessary because idle sockets are
7349 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557350 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007351
7352 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507353 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007354}
7355
maksim.sisov0adf8592016-07-15 06:25:567356// Grab a socket, use it, and put it back into the pool. Then, make
7357// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017358TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567359 HttpRequestInfo request;
7360 request.method = "GET";
7361 request.url = GURL("http://www.example.org/");
7362 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107363 request.traffic_annotation =
7364 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567365
7366 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7367
bnc691fda62016-08-12 00:43:167368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567369
7370 MockRead data_reads[] = {
7371 // A part of the response body is received with the response headers.
7372 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7373 // The rest of the response body is received in two parts.
7374 MockRead("lo"), MockRead(" world"),
7375 MockRead("junk"), // Should not be read!!
7376 MockRead(SYNCHRONOUS, OK),
7377 };
7378
7379 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7380 session_deps_.socket_factory->AddSocketDataProvider(&data);
7381
7382 TestCompletionCallback callback;
7383
tfarina42834112016-09-22 13:38:207384 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7386
7387 EXPECT_THAT(callback.GetResult(rv), IsOk());
7388
bnc691fda62016-08-12 00:43:167389 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567390 ASSERT_TRUE(response);
7391 EXPECT_TRUE(response->headers);
7392 std::string status_line = response->headers->GetStatusLine();
7393 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7394
7395 // Make memory critical notification and ensure the transaction still has been
7396 // operating right.
7397 base::MemoryPressureListener::NotifyMemoryPressure(
7398 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7399 base::RunLoop().RunUntilIdle();
7400
7401 // Socket should not be flushed as long as it is not idle.
7402 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7403
7404 std::string response_data;
bnc691fda62016-08-12 00:43:167405 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567406 EXPECT_THAT(rv, IsOk());
7407 EXPECT_EQ("hello world", response_data);
7408
7409 // Empty the current queue. This is necessary because idle sockets are
7410 // added to the connection pool asynchronously with a PostTask.
7411 base::RunLoop().RunUntilIdle();
7412
7413 // We now check to make sure the socket was added back to the pool.
7414 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7415
7416 // Idle sockets should be flushed now.
7417 base::MemoryPressureListener::NotifyMemoryPressure(
7418 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7419 base::RunLoop().RunUntilIdle();
7420
7421 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7422}
7423
yucliu48f235d2018-01-11 00:59:557424// Disable idle socket closing on memory pressure.
7425// Grab a socket, use it, and put it back into the pool. Then, make
7426// low memory notification and ensure the socket pool is NOT flushed.
7427TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7428 HttpRequestInfo request;
7429 request.method = "GET";
7430 request.url = GURL("http://www.example.org/");
7431 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107432 request.traffic_annotation =
7433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557434
7435 // Disable idle socket closing on memory pressure.
7436 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7438
7439 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7440
7441 MockRead data_reads[] = {
7442 // A part of the response body is received with the response headers.
7443 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7444 // The rest of the response body is received in two parts.
7445 MockRead("lo"), MockRead(" world"),
7446 MockRead("junk"), // Should not be read!!
7447 MockRead(SYNCHRONOUS, OK),
7448 };
7449
7450 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7451 session_deps_.socket_factory->AddSocketDataProvider(&data);
7452
7453 TestCompletionCallback callback;
7454
7455 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7457
7458 EXPECT_THAT(callback.GetResult(rv), IsOk());
7459
7460 const HttpResponseInfo* response = trans.GetResponseInfo();
7461 ASSERT_TRUE(response);
7462 EXPECT_TRUE(response->headers);
7463 std::string status_line = response->headers->GetStatusLine();
7464 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7465
7466 // Make memory critical notification and ensure the transaction still has been
7467 // operating right.
7468 base::MemoryPressureListener::NotifyMemoryPressure(
7469 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7470 base::RunLoop().RunUntilIdle();
7471
7472 // Socket should not be flushed as long as it is not idle.
7473 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7474
7475 std::string response_data;
7476 rv = ReadTransaction(&trans, &response_data);
7477 EXPECT_THAT(rv, IsOk());
7478 EXPECT_EQ("hello world", response_data);
7479
7480 // Empty the current queue. This is necessary because idle sockets are
7481 // added to the connection pool asynchronously with a PostTask.
7482 base::RunLoop().RunUntilIdle();
7483
7484 // We now check to make sure the socket was added back to the pool.
7485 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7486
7487 // Idle sockets should NOT be flushed on moderate memory pressure.
7488 base::MemoryPressureListener::NotifyMemoryPressure(
7489 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7490 base::RunLoop().RunUntilIdle();
7491
7492 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7493
7494 // Idle sockets should NOT be flushed on critical memory pressure.
7495 base::MemoryPressureListener::NotifyMemoryPressure(
7496 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7497 base::RunLoop().RunUntilIdle();
7498
7499 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7500}
7501
maksim.sisov0adf8592016-07-15 06:25:567502// Grab an SSL socket, use it, and put it back into the pool. Then, make
7503// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017504TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567505 HttpRequestInfo request;
7506 request.method = "GET";
7507 request.url = GURL("https://www.example.org/");
7508 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107509 request.traffic_annotation =
7510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567511
7512 MockWrite data_writes[] = {
7513 MockWrite("GET / HTTP/1.1\r\n"
7514 "Host: www.example.org\r\n"
7515 "Connection: keep-alive\r\n\r\n"),
7516 };
7517
7518 MockRead data_reads[] = {
7519 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7520 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7521
7522 SSLSocketDataProvider ssl(ASYNC, OK);
7523 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7524
7525 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7526 arraysize(data_writes));
7527 session_deps_.socket_factory->AddSocketDataProvider(&data);
7528
7529 TestCompletionCallback callback;
7530
7531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567533
7534 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207535 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567536
7537 EXPECT_THAT(callback.GetResult(rv), IsOk());
7538
bnc691fda62016-08-12 00:43:167539 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567540 ASSERT_TRUE(response);
7541 ASSERT_TRUE(response->headers);
7542 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7543
7544 // Make memory critical notification and ensure the transaction still has been
7545 // operating right.
7546 base::MemoryPressureListener::NotifyMemoryPressure(
7547 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7548 base::RunLoop().RunUntilIdle();
7549
7550 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7551
7552 std::string response_data;
bnc691fda62016-08-12 00:43:167553 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567554 EXPECT_THAT(rv, IsOk());
7555 EXPECT_EQ("hello world", response_data);
7556
7557 // Empty the current queue. This is necessary because idle sockets are
7558 // added to the connection pool asynchronously with a PostTask.
7559 base::RunLoop().RunUntilIdle();
7560
7561 // We now check to make sure the socket was added back to the pool.
7562 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7563
7564 // Make memory notification once again and ensure idle socket is closed.
7565 base::MemoryPressureListener::NotifyMemoryPressure(
7566 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7567 base::RunLoop().RunUntilIdle();
7568
7569 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7570}
7571
[email protected]b4404c02009-04-10 16:38:527572// Make sure that we recycle a socket after a zero-length response.
7573// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017574TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427575 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527576 request.method = "GET";
bncce36dca22015-04-21 22:11:237577 request.url = GURL(
7578 "http://www.example.org/csi?v=3&s=web&action=&"
7579 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7580 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7581 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:107582 request.traffic_annotation =
7583 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527584
danakj1fd259a02016-04-16 03:17:097585 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277586
[email protected]b4404c02009-04-10 16:38:527587 MockRead data_reads[] = {
7588 MockRead("HTTP/1.1 204 No Content\r\n"
7589 "Content-Length: 0\r\n"
7590 "Content-Type: text/html\r\n\r\n"),
7591 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067592 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527593 };
7594
[email protected]31a2bfe2010-02-09 08:03:397595 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077596 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527597
mmenkecc2298e2015-12-07 18:20:187598 // Transaction must be created after the MockReads, so it's destroyed before
7599 // them.
bnc691fda62016-08-12 00:43:167600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187601
[email protected]49639fa2011-12-20 23:22:417602 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527603
tfarina42834112016-09-22 13:38:207604 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527606
7607 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017608 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527609
bnc691fda62016-08-12 00:43:167610 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527611 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527612
wezca1070932016-05-26 20:30:527613 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527614 std::string status_line = response->headers->GetStatusLine();
7615 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7616
[email protected]90499482013-06-01 00:39:507617 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527618
7619 std::string response_data;
bnc691fda62016-08-12 00:43:167620 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017621 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527622 EXPECT_EQ("", response_data);
7623
7624 // Empty the current queue. This is necessary because idle sockets are
7625 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557626 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527627
7628 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507629 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527630}
7631
bncd16676a2016-07-20 16:23:017632TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097633 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227634 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197635 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227636 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277637
[email protected]1c773ea12009-04-28 19:58:427638 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517639 // Transaction 1: a GET request that succeeds. The socket is recycled
7640 // after use.
7641 request[0].method = "GET";
7642 request[0].url = GURL("http://www.google.com/");
7643 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107644 request[0].traffic_annotation =
7645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517646 // Transaction 2: a POST request. Reuses the socket kept alive from
7647 // transaction 1. The first attempts fails when writing the POST data.
7648 // This causes the transaction to retry with a new socket. The second
7649 // attempt succeeds.
7650 request[1].method = "POST";
7651 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277652 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517653 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107654 request[1].traffic_annotation =
7655 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517656
danakj1fd259a02016-04-16 03:17:097657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517658
7659 // The first socket is used for transaction 1 and the first attempt of
7660 // transaction 2.
7661
7662 // The response of transaction 1.
7663 MockRead data_reads1[] = {
7664 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7665 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067666 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517667 };
7668 // The mock write results of transaction 1 and the first attempt of
7669 // transaction 2.
7670 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067671 MockWrite(SYNCHRONOUS, 64), // GET
7672 MockWrite(SYNCHRONOUS, 93), // POST
7673 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517674 };
[email protected]31a2bfe2010-02-09 08:03:397675 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7676 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517677
7678 // The second socket is used for the second attempt of transaction 2.
7679
7680 // The response of transaction 2.
7681 MockRead data_reads2[] = {
7682 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7683 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067684 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517685 };
7686 // The mock write results of the second attempt of transaction 2.
7687 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067688 MockWrite(SYNCHRONOUS, 93), // POST
7689 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517690 };
[email protected]31a2bfe2010-02-09 08:03:397691 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7692 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517693
[email protected]bb88e1d32013-05-03 23:11:077694 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7695 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517696
thestig9d3bb0c2015-01-24 00:49:517697 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517698 "hello world", "welcome"
7699 };
7700
7701 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517703
[email protected]49639fa2011-12-20 23:22:417704 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517705
tfarina42834112016-09-22 13:38:207706 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517708
7709 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017710 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517711
bnc691fda62016-08-12 00:43:167712 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527713 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517714
wezca1070932016-05-26 20:30:527715 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517716 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7717
7718 std::string response_data;
bnc691fda62016-08-12 00:43:167719 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017720 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517721 EXPECT_EQ(kExpectedResponseData[i], response_data);
7722 }
7723}
[email protected]f9ee6b52008-11-08 06:46:237724
7725// Test the request-challenge-retry sequence for basic auth when there is
7726// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167727// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017728TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427729 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237730 request.method = "GET";
bncce36dca22015-04-21 22:11:237731 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417732 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107733 request.traffic_annotation =
7734 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297735
danakj1fd259a02016-04-16 03:17:097736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277738
[email protected]a97cca42009-08-14 01:00:297739 // The password contains an escaped character -- for this test to pass it
7740 // will need to be unescaped by HttpNetworkTransaction.
7741 EXPECT_EQ("b%40r", request.url.password());
7742
[email protected]f9ee6b52008-11-08 06:46:237743 MockWrite data_writes1[] = {
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\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237748 };
7749
7750 MockRead data_reads1[] = {
7751 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7752 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7753 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067754 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237755 };
7756
[email protected]2262e3a2012-05-22 16:08:167757 // After the challenge above, the transaction will be restarted using the
7758 // identity from the url (foo, b@r) to answer the challenge.
7759 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237760 MockWrite(
7761 "GET / HTTP/1.1\r\n"
7762 "Host: www.example.org\r\n"
7763 "Connection: keep-alive\r\n"
7764 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167765 };
7766
7767 MockRead data_reads2[] = {
7768 MockRead("HTTP/1.0 200 OK\r\n"),
7769 MockRead("Content-Length: 100\r\n\r\n"),
7770 MockRead(SYNCHRONOUS, OK),
7771 };
7772
[email protected]31a2bfe2010-02-09 08:03:397773 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7774 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167775 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7776 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7778 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237779
[email protected]49639fa2011-12-20 23:22:417780 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207781 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237783 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017784 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167785 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167786
7787 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167788 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167790 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017791 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167792 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227793
bnc691fda62016-08-12 00:43:167794 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527795 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167796
7797 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527798 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167799
7800 EXPECT_EQ(100, response->headers->GetContentLength());
7801
7802 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557803 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167804}
7805
7806// Test the request-challenge-retry sequence for basic auth when there is an
7807// incorrect identity in the URL. The identity from the URL should be used only
7808// once.
bncd16676a2016-07-20 16:23:017809TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167810 HttpRequestInfo request;
7811 request.method = "GET";
7812 // Note: the URL has a username:password in it. The password "baz" is
7813 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237814 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167815
7816 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107817 request.traffic_annotation =
7818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167819
danakj1fd259a02016-04-16 03:17:097820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167822
7823 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237824 MockWrite(
7825 "GET / HTTP/1.1\r\n"
7826 "Host: www.example.org\r\n"
7827 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167828 };
7829
7830 MockRead data_reads1[] = {
7831 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7832 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7833 MockRead("Content-Length: 10\r\n\r\n"),
7834 MockRead(SYNCHRONOUS, ERR_FAILED),
7835 };
7836
7837 // After the challenge above, the transaction will be restarted using the
7838 // identity from the url (foo, baz) to answer the challenge.
7839 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237840 MockWrite(
7841 "GET / HTTP/1.1\r\n"
7842 "Host: www.example.org\r\n"
7843 "Connection: keep-alive\r\n"
7844 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167845 };
7846
7847 MockRead data_reads2[] = {
7848 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7849 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7850 MockRead("Content-Length: 10\r\n\r\n"),
7851 MockRead(SYNCHRONOUS, ERR_FAILED),
7852 };
7853
7854 // After the challenge above, the transaction will be restarted using the
7855 // identity supplied by the user (foo, bar) to answer the challenge.
7856 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237857 MockWrite(
7858 "GET / HTTP/1.1\r\n"
7859 "Host: www.example.org\r\n"
7860 "Connection: keep-alive\r\n"
7861 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167862 };
7863
7864 MockRead data_reads3[] = {
7865 MockRead("HTTP/1.0 200 OK\r\n"),
7866 MockRead("Content-Length: 100\r\n\r\n"),
7867 MockRead(SYNCHRONOUS, OK),
7868 };
7869
7870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7871 data_writes1, arraysize(data_writes1));
7872 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7873 data_writes2, arraysize(data_writes2));
7874 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7875 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7877 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7878 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167879
7880 TestCompletionCallback callback1;
7881
tfarina42834112016-09-22 13:38:207882 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167884
7885 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017886 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167887
bnc691fda62016-08-12 00:43:167888 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167889 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167890 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167892 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017893 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167894 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167895
bnc691fda62016-08-12 00:43:167896 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527897 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167898 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7899
7900 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167901 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167903 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017904 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167905 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167906
bnc691fda62016-08-12 00:43:167907 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527908 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167909
7910 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527911 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167912
7913 EXPECT_EQ(100, response->headers->GetContentLength());
7914
[email protected]ea9dc9a2009-09-05 00:43:327915 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557916 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327917}
7918
[email protected]2217aa22013-10-11 03:03:547919
7920// Test the request-challenge-retry sequence for basic auth when there is a
7921// correct identity in the URL, but its use is being suppressed. The identity
7922// from the URL should never be used.
bncd16676a2016-07-20 16:23:017923TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547924 HttpRequestInfo request;
7925 request.method = "GET";
bncce36dca22015-04-21 22:11:237926 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547927 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:107928 request.traffic_annotation =
7929 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547930
danakj1fd259a02016-04-16 03:17:097931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547933
7934 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237935 MockWrite(
7936 "GET / HTTP/1.1\r\n"
7937 "Host: www.example.org\r\n"
7938 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547939 };
7940
7941 MockRead data_reads1[] = {
7942 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7943 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7944 MockRead("Content-Length: 10\r\n\r\n"),
7945 MockRead(SYNCHRONOUS, ERR_FAILED),
7946 };
7947
7948 // After the challenge above, the transaction will be restarted using the
7949 // identity supplied by the user, not the one in the URL, to answer the
7950 // challenge.
7951 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237952 MockWrite(
7953 "GET / HTTP/1.1\r\n"
7954 "Host: www.example.org\r\n"
7955 "Connection: keep-alive\r\n"
7956 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547957 };
7958
7959 MockRead data_reads3[] = {
7960 MockRead("HTTP/1.0 200 OK\r\n"),
7961 MockRead("Content-Length: 100\r\n\r\n"),
7962 MockRead(SYNCHRONOUS, OK),
7963 };
7964
7965 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7966 data_writes1, arraysize(data_writes1));
7967 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7968 data_writes3, arraysize(data_writes3));
7969 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7970 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7971
7972 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207973 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017974 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547975 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017976 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167977 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547978
bnc691fda62016-08-12 00:43:167979 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527980 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547981 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7982
7983 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167984 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547986 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017987 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167988 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547989
bnc691fda62016-08-12 00:43:167990 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527991 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547992
7993 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527994 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547995 EXPECT_EQ(100, response->headers->GetContentLength());
7996
7997 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557998 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547999}
8000
[email protected]f9ee6b52008-11-08 06:46:238001// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018002TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238004
8005 // Transaction 1: authenticate (foo, bar) on MyRealm1
8006 {
[email protected]1c773ea12009-04-28 19:58:428007 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238008 request.method = "GET";
bncce36dca22015-04-21 22:11:238009 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108010 request.traffic_annotation =
8011 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238012
bnc691fda62016-08-12 00:43:168013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278014
[email protected]f9ee6b52008-11-08 06:46:238015 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238016 MockWrite(
8017 "GET /x/y/z HTTP/1.1\r\n"
8018 "Host: www.example.org\r\n"
8019 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238020 };
8021
8022 MockRead data_reads1[] = {
8023 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8024 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8025 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068026 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238027 };
8028
8029 // Resend with authorization (username=foo, password=bar)
8030 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238031 MockWrite(
8032 "GET /x/y/z HTTP/1.1\r\n"
8033 "Host: www.example.org\r\n"
8034 "Connection: keep-alive\r\n"
8035 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238036 };
8037
8038 // Sever accepts the authorization.
8039 MockRead data_reads2[] = {
8040 MockRead("HTTP/1.0 200 OK\r\n"),
8041 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068042 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238043 };
8044
[email protected]31a2bfe2010-02-09 08:03:398045 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8046 data_writes1, arraysize(data_writes1));
8047 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8048 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078049 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8050 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238051
[email protected]49639fa2011-12-20 23:22:418052 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238053
tfarina42834112016-09-22 13:38:208054 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238056
8057 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018058 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238059
bnc691fda62016-08-12 00:43:168060 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528061 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048062 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238063
[email protected]49639fa2011-12-20 23:22:418064 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238065
bnc691fda62016-08-12 00:43:168066 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8067 callback2.callback());
robpercival214763f2016-07-01 23:27:018068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238069
8070 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018071 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238072
bnc691fda62016-08-12 00:43:168073 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528074 ASSERT_TRUE(response);
8075 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238076 EXPECT_EQ(100, response->headers->GetContentLength());
8077 }
8078
8079 // ------------------------------------------------------------------------
8080
8081 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8082 {
[email protected]1c773ea12009-04-28 19:58:428083 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238084 request.method = "GET";
8085 // Note that Transaction 1 was at /x/y/z, so this is in the same
8086 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238087 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108088 request.traffic_annotation =
8089 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238090
bnc691fda62016-08-12 00:43:168091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278092
[email protected]f9ee6b52008-11-08 06:46:238093 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238094 MockWrite(
8095 "GET /x/y/a/b HTTP/1.1\r\n"
8096 "Host: www.example.org\r\n"
8097 "Connection: keep-alive\r\n"
8098 // Send preemptive authorization for MyRealm1
8099 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238100 };
8101
8102 // The server didn't like the preemptive authorization, and
8103 // challenges us for a different realm (MyRealm2).
8104 MockRead data_reads1[] = {
8105 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8106 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8107 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068108 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238109 };
8110
8111 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8112 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238113 MockWrite(
8114 "GET /x/y/a/b HTTP/1.1\r\n"
8115 "Host: www.example.org\r\n"
8116 "Connection: keep-alive\r\n"
8117 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238118 };
8119
8120 // Sever accepts the authorization.
8121 MockRead data_reads2[] = {
8122 MockRead("HTTP/1.0 200 OK\r\n"),
8123 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068124 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238125 };
8126
[email protected]31a2bfe2010-02-09 08:03:398127 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8128 data_writes1, arraysize(data_writes1));
8129 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8130 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078131 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8132 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238133
[email protected]49639fa2011-12-20 23:22:418134 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238135
tfarina42834112016-09-22 13:38:208136 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018137 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238138
8139 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018140 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238141
bnc691fda62016-08-12 00:43:168142 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528143 ASSERT_TRUE(response);
8144 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048145 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438146 EXPECT_EQ("http://www.example.org",
8147 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048148 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198149 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238150
[email protected]49639fa2011-12-20 23:22:418151 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238152
bnc691fda62016-08-12 00:43:168153 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8154 callback2.callback());
robpercival214763f2016-07-01 23:27:018155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238156
8157 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018158 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238159
bnc691fda62016-08-12 00:43:168160 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528161 ASSERT_TRUE(response);
8162 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238163 EXPECT_EQ(100, response->headers->GetContentLength());
8164 }
8165
8166 // ------------------------------------------------------------------------
8167
8168 // Transaction 3: Resend a request in MyRealm's protection space --
8169 // succeed with preemptive authorization.
8170 {
[email protected]1c773ea12009-04-28 19:58:428171 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238172 request.method = "GET";
bncce36dca22015-04-21 22:11:238173 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108174 request.traffic_annotation =
8175 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238176
bnc691fda62016-08-12 00:43:168177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278178
[email protected]f9ee6b52008-11-08 06:46:238179 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238180 MockWrite(
8181 "GET /x/y/z2 HTTP/1.1\r\n"
8182 "Host: www.example.org\r\n"
8183 "Connection: keep-alive\r\n"
8184 // The authorization for MyRealm1 gets sent preemptively
8185 // (since the url is in the same protection space)
8186 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238187 };
8188
8189 // Sever accepts the preemptive authorization
8190 MockRead data_reads1[] = {
8191 MockRead("HTTP/1.0 200 OK\r\n"),
8192 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068193 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238194 };
8195
[email protected]31a2bfe2010-02-09 08:03:398196 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8197 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238199
[email protected]49639fa2011-12-20 23:22:418200 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238201
tfarina42834112016-09-22 13:38:208202 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238204
8205 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018206 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238207
bnc691fda62016-08-12 00:43:168208 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528209 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238210
wezca1070932016-05-26 20:30:528211 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238212 EXPECT_EQ(100, response->headers->GetContentLength());
8213 }
8214
8215 // ------------------------------------------------------------------------
8216
8217 // Transaction 4: request another URL in MyRealm (however the
8218 // url is not known to belong to the protection space, so no pre-auth).
8219 {
[email protected]1c773ea12009-04-28 19:58:428220 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238221 request.method = "GET";
bncce36dca22015-04-21 22:11:238222 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108223 request.traffic_annotation =
8224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238225
bnc691fda62016-08-12 00:43:168226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278227
[email protected]f9ee6b52008-11-08 06:46:238228 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238229 MockWrite(
8230 "GET /x/1 HTTP/1.1\r\n"
8231 "Host: www.example.org\r\n"
8232 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238233 };
8234
8235 MockRead data_reads1[] = {
8236 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8237 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8238 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068239 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238240 };
8241
8242 // Resend with authorization from MyRealm's cache.
8243 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238244 MockWrite(
8245 "GET /x/1 HTTP/1.1\r\n"
8246 "Host: www.example.org\r\n"
8247 "Connection: keep-alive\r\n"
8248 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238249 };
8250
8251 // Sever accepts the authorization.
8252 MockRead data_reads2[] = {
8253 MockRead("HTTP/1.0 200 OK\r\n"),
8254 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068255 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238256 };
8257
[email protected]31a2bfe2010-02-09 08:03:398258 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8259 data_writes1, arraysize(data_writes1));
8260 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8261 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078262 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8263 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238264
[email protected]49639fa2011-12-20 23:22:418265 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238266
tfarina42834112016-09-22 13:38:208267 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238269
8270 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018271 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238272
bnc691fda62016-08-12 00:43:168273 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418274 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168275 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018276 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228277 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018278 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168279 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228280
bnc691fda62016-08-12 00:43:168281 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528282 ASSERT_TRUE(response);
8283 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238284 EXPECT_EQ(100, response->headers->GetContentLength());
8285 }
8286
8287 // ------------------------------------------------------------------------
8288
8289 // Transaction 5: request a URL in MyRealm, but the server rejects the
8290 // cached identity. Should invalidate and re-prompt.
8291 {
[email protected]1c773ea12009-04-28 19:58:428292 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238293 request.method = "GET";
bncce36dca22015-04-21 22:11:238294 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:108295 request.traffic_annotation =
8296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238297
bnc691fda62016-08-12 00:43:168298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278299
[email protected]f9ee6b52008-11-08 06:46:238300 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238301 MockWrite(
8302 "GET /p/q/t HTTP/1.1\r\n"
8303 "Host: www.example.org\r\n"
8304 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238305 };
8306
8307 MockRead data_reads1[] = {
8308 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8309 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8310 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068311 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238312 };
8313
8314 // Resend with authorization from cache for MyRealm.
8315 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238316 MockWrite(
8317 "GET /p/q/t HTTP/1.1\r\n"
8318 "Host: www.example.org\r\n"
8319 "Connection: keep-alive\r\n"
8320 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238321 };
8322
8323 // Sever rejects the authorization.
8324 MockRead data_reads2[] = {
8325 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8326 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8327 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068328 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238329 };
8330
8331 // At this point we should prompt for new credentials for MyRealm.
8332 // Restart with username=foo3, password=foo4.
8333 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238334 MockWrite(
8335 "GET /p/q/t HTTP/1.1\r\n"
8336 "Host: www.example.org\r\n"
8337 "Connection: keep-alive\r\n"
8338 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238339 };
8340
8341 // Sever accepts the authorization.
8342 MockRead data_reads3[] = {
8343 MockRead("HTTP/1.0 200 OK\r\n"),
8344 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068345 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238346 };
8347
[email protected]31a2bfe2010-02-09 08:03:398348 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8349 data_writes1, arraysize(data_writes1));
8350 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8351 data_writes2, arraysize(data_writes2));
8352 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8353 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078354 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8355 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8356 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238357
[email protected]49639fa2011-12-20 23:22:418358 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238359
tfarina42834112016-09-22 13:38:208360 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018361 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238362
8363 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018364 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238365
bnc691fda62016-08-12 00:43:168366 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418367 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168368 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228370 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018371 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168372 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228373
bnc691fda62016-08-12 00:43:168374 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528375 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048376 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238377
[email protected]49639fa2011-12-20 23:22:418378 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238379
bnc691fda62016-08-12 00:43:168380 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8381 callback3.callback());
robpercival214763f2016-07-01 23:27:018382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238383
[email protected]0757e7702009-03-27 04:00:228384 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018385 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238386
bnc691fda62016-08-12 00:43:168387 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528388 ASSERT_TRUE(response);
8389 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238390 EXPECT_EQ(100, response->headers->GetContentLength());
8391 }
8392}
[email protected]89ceba9a2009-03-21 03:46:068393
[email protected]3c32c5f2010-05-18 15:18:128394// Tests that nonce count increments when multiple auth attempts
8395// are started with the same nonce.
bncd16676a2016-07-20 16:23:018396TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448397 HttpAuthHandlerDigest::Factory* digest_factory =
8398 new HttpAuthHandlerDigest::Factory();
8399 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8400 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8401 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078402 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128404
8405 // Transaction 1: authenticate (foo, bar) on MyRealm1
8406 {
[email protected]3c32c5f2010-05-18 15:18:128407 HttpRequestInfo request;
8408 request.method = "GET";
bncce36dca22015-04-21 22:11:238409 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108410 request.traffic_annotation =
8411 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128412
bnc691fda62016-08-12 00:43:168413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278414
[email protected]3c32c5f2010-05-18 15:18:128415 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238416 MockWrite(
8417 "GET /x/y/z HTTP/1.1\r\n"
8418 "Host: www.example.org\r\n"
8419 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128420 };
8421
8422 MockRead data_reads1[] = {
8423 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8424 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8425 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068426 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128427 };
8428
8429 // Resend with authorization (username=foo, password=bar)
8430 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238431 MockWrite(
8432 "GET /x/y/z HTTP/1.1\r\n"
8433 "Host: www.example.org\r\n"
8434 "Connection: keep-alive\r\n"
8435 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8436 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8437 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8438 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128439 };
8440
8441 // Sever accepts the authorization.
8442 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088443 MockRead("HTTP/1.0 200 OK\r\n"),
8444 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128445 };
8446
8447 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8448 data_writes1, arraysize(data_writes1));
8449 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8450 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078451 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8452 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128453
[email protected]49639fa2011-12-20 23:22:418454 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128455
tfarina42834112016-09-22 13:38:208456 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128458
8459 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018460 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128461
bnc691fda62016-08-12 00:43:168462 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528463 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048464 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128465
[email protected]49639fa2011-12-20 23:22:418466 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128467
bnc691fda62016-08-12 00:43:168468 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8469 callback2.callback());
robpercival214763f2016-07-01 23:27:018470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128471
8472 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018473 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128474
bnc691fda62016-08-12 00:43:168475 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528476 ASSERT_TRUE(response);
8477 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128478 }
8479
8480 // ------------------------------------------------------------------------
8481
8482 // Transaction 2: Request another resource in digestive's protection space.
8483 // This will preemptively add an Authorization header which should have an
8484 // "nc" value of 2 (as compared to 1 in the first use.
8485 {
[email protected]3c32c5f2010-05-18 15:18:128486 HttpRequestInfo request;
8487 request.method = "GET";
8488 // Note that Transaction 1 was at /x/y/z, so this is in the same
8489 // protection space as digest.
bncce36dca22015-04-21 22:11:238490 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108491 request.traffic_annotation =
8492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128493
bnc691fda62016-08-12 00:43:168494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278495
[email protected]3c32c5f2010-05-18 15:18:128496 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238497 MockWrite(
8498 "GET /x/y/a/b HTTP/1.1\r\n"
8499 "Host: www.example.org\r\n"
8500 "Connection: keep-alive\r\n"
8501 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8502 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8503 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8504 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128505 };
8506
8507 // Sever accepts the authorization.
8508 MockRead data_reads1[] = {
8509 MockRead("HTTP/1.0 200 OK\r\n"),
8510 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068511 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128512 };
8513
8514 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8515 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078516 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128517
[email protected]49639fa2011-12-20 23:22:418518 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128519
tfarina42834112016-09-22 13:38:208520 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018521 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128522
8523 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018524 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128525
bnc691fda62016-08-12 00:43:168526 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528527 ASSERT_TRUE(response);
8528 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128529 }
8530}
8531
[email protected]89ceba9a2009-03-21 03:46:068532// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018533TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068534 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168536 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068537
8538 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168539 trans.read_buf_ = new IOBuffer(15);
8540 trans.read_buf_len_ = 15;
8541 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068542
8543 // Setup state in response_
bnc691fda62016-08-12 00:43:168544 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578545 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088546 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578547 response->response_time = base::Time::Now();
8548 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068549
8550 { // Setup state for response_.vary_data
8551 HttpRequestInfo request;
8552 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8553 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278554 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438555 request.extra_headers.SetHeader("Foo", "1");
8556 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508557 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068558 }
8559
8560 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168561 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068562
8563 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168564 EXPECT_FALSE(trans.read_buf_);
8565 EXPECT_EQ(0, trans.read_buf_len_);
8566 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528567 EXPECT_FALSE(response->auth_challenge);
8568 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048569 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088570 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578571 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068572}
8573
[email protected]bacff652009-03-31 17:50:338574// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018575TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338576 HttpRequestInfo request;
8577 request.method = "GET";
bncce36dca22015-04-21 22:11:238578 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108579 request.traffic_annotation =
8580 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338581
danakj1fd259a02016-04-16 03:17:098582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278584
[email protected]bacff652009-03-31 17:50:338585 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238586 MockWrite(
8587 "GET / HTTP/1.1\r\n"
8588 "Host: www.example.org\r\n"
8589 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338590 };
8591
8592 MockRead data_reads[] = {
8593 MockRead("HTTP/1.0 200 OK\r\n"),
8594 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8595 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068596 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338597 };
8598
[email protected]5ecc992a42009-11-11 01:41:598599 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398600 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8601 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068602 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8603 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338604
[email protected]bb88e1d32013-05-03 23:11:078605 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8606 session_deps_.socket_factory->AddSocketDataProvider(&data);
8607 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338609
[email protected]49639fa2011-12-20 23:22:418610 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338611
tfarina42834112016-09-22 13:38:208612 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338614
8615 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018616 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338617
bnc691fda62016-08-12 00:43:168618 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338620
8621 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018622 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338623
bnc691fda62016-08-12 00:43:168624 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338625
wezca1070932016-05-26 20:30:528626 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338627 EXPECT_EQ(100, response->headers->GetContentLength());
8628}
8629
8630// Test HTTPS connections to a site with a bad certificate, going through a
8631// proxy
bncd16676a2016-07-20 16:23:018632TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498633 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8634 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338635
8636 HttpRequestInfo request;
8637 request.method = "GET";
bncce36dca22015-04-21 22:11:238638 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108639 request.traffic_annotation =
8640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338641
8642 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178643 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8644 "Host: www.example.org:443\r\n"
8645 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338646 };
8647
8648 MockRead proxy_reads[] = {
8649 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068650 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338651 };
8652
8653 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178654 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8655 "Host: www.example.org:443\r\n"
8656 "Proxy-Connection: keep-alive\r\n\r\n"),
8657 MockWrite("GET / HTTP/1.1\r\n"
8658 "Host: www.example.org\r\n"
8659 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338660 };
8661
8662 MockRead data_reads[] = {
8663 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8664 MockRead("HTTP/1.0 200 OK\r\n"),
8665 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8666 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068667 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338668 };
8669
[email protected]31a2bfe2010-02-09 08:03:398670 StaticSocketDataProvider ssl_bad_certificate(
8671 proxy_reads, arraysize(proxy_reads),
8672 proxy_writes, arraysize(proxy_writes));
8673 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8674 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068675 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8676 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338677
[email protected]bb88e1d32013-05-03 23:11:078678 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8679 session_deps_.socket_factory->AddSocketDataProvider(&data);
8680 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338682
[email protected]49639fa2011-12-20 23:22:418683 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338684
8685 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078686 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338687
danakj1fd259a02016-04-16 03:17:098688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338690
tfarina42834112016-09-22 13:38:208691 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338693
8694 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018695 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338696
bnc691fda62016-08-12 00:43:168697 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338699
8700 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018701 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338702
bnc691fda62016-08-12 00:43:168703 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338704
wezca1070932016-05-26 20:30:528705 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338706 EXPECT_EQ(100, response->headers->GetContentLength());
8707 }
8708}
8709
[email protected]2df19bb2010-08-25 20:13:468710
8711// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018712TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598713 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498714 ProxyResolutionService::CreateFixedFromPacResult(
8715 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518716 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078717 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468718
8719 HttpRequestInfo request;
8720 request.method = "GET";
bncce36dca22015-04-21 22:11:238721 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108722 request.traffic_annotation =
8723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468724
8725 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178726 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8727 "Host: www.example.org:443\r\n"
8728 "Proxy-Connection: keep-alive\r\n\r\n"),
8729 MockWrite("GET / HTTP/1.1\r\n"
8730 "Host: www.example.org\r\n"
8731 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468732 };
8733
8734 MockRead data_reads[] = {
8735 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8736 MockRead("HTTP/1.1 200 OK\r\n"),
8737 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8738 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068739 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468740 };
8741
8742 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8743 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068744 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8745 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468746
[email protected]bb88e1d32013-05-03 23:11:078747 session_deps_.socket_factory->AddSocketDataProvider(&data);
8748 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8749 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468750
[email protected]49639fa2011-12-20 23:22:418751 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468752
danakj1fd259a02016-04-16 03:17:098753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468755
tfarina42834112016-09-22 13:38:208756 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468758
8759 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018760 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168761 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468762
wezca1070932016-05-26 20:30:528763 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468764
tbansal2ecbbc72016-10-06 17:15:478765 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468766 EXPECT_TRUE(response->headers->IsKeepAlive());
8767 EXPECT_EQ(200, response->headers->response_code());
8768 EXPECT_EQ(100, response->headers->GetContentLength());
8769 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208770
8771 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168772 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208773 TestLoadTimingNotReusedWithPac(load_timing_info,
8774 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468775}
8776
[email protected]511f6f52010-12-17 03:58:298777// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018778TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598779 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498780 ProxyResolutionService::CreateFixedFromPacResult(
8781 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518782 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078783 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298784
8785 HttpRequestInfo request;
8786 request.method = "GET";
bncce36dca22015-04-21 22:11:238787 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108788 request.traffic_annotation =
8789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298790
8791 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178792 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8793 "Host: www.example.org:443\r\n"
8794 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298795 };
8796
8797 MockRead data_reads[] = {
8798 MockRead("HTTP/1.1 302 Redirect\r\n"),
8799 MockRead("Location: http://login.example.com/\r\n"),
8800 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068801 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298802 };
8803
8804 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8805 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068806 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298807
[email protected]bb88e1d32013-05-03 23:11:078808 session_deps_.socket_factory->AddSocketDataProvider(&data);
8809 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298810
[email protected]49639fa2011-12-20 23:22:418811 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298812
danakj1fd259a02016-04-16 03:17:098813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298815
tfarina42834112016-09-22 13:38:208816 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298818
8819 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018820 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168821 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298822
wezca1070932016-05-26 20:30:528823 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298824
8825 EXPECT_EQ(302, response->headers->response_code());
8826 std::string url;
8827 EXPECT_TRUE(response->headers->IsRedirect(&url));
8828 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208829
8830 // In the case of redirects from proxies, HttpNetworkTransaction returns
8831 // timing for the proxy connection instead of the connection to the host,
8832 // and no send / receive times.
8833 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8834 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168835 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208836
8837 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198838 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208839
8840 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8841 EXPECT_LE(load_timing_info.proxy_resolve_start,
8842 load_timing_info.proxy_resolve_end);
8843 EXPECT_LE(load_timing_info.proxy_resolve_end,
8844 load_timing_info.connect_timing.connect_start);
8845 ExpectConnectTimingHasTimes(
8846 load_timing_info.connect_timing,
8847 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8848
8849 EXPECT_TRUE(load_timing_info.send_start.is_null());
8850 EXPECT_TRUE(load_timing_info.send_end.is_null());
8851 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298852}
8853
8854// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018855TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498856 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8857 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298858
8859 HttpRequestInfo request;
8860 request.method = "GET";
bncce36dca22015-04-21 22:11:238861 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108862 request.traffic_annotation =
8863 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298864
bncdf80d44fd2016-07-15 20:27:418865 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238866 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418867 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088868 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298869 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418870 CreateMockWrite(conn, 0, SYNCHRONOUS),
8871 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298872 };
8873
8874 static const char* const kExtraHeaders[] = {
8875 "location",
8876 "http://login.example.com/",
8877 };
bnc42331402016-07-25 13:36:158878 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238879 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298880 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418881 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298882 };
8883
rch8e6c6c42015-05-01 14:05:138884 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8885 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068886 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368887 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298888
[email protected]bb88e1d32013-05-03 23:11:078889 session_deps_.socket_factory->AddSocketDataProvider(&data);
8890 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298891
[email protected]49639fa2011-12-20 23:22:418892 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298893
danakj1fd259a02016-04-16 03:17:098894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298896
tfarina42834112016-09-22 13:38:208897 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298899
8900 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018901 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168902 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298903
wezca1070932016-05-26 20:30:528904 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298905
8906 EXPECT_EQ(302, response->headers->response_code());
8907 std::string url;
8908 EXPECT_TRUE(response->headers->IsRedirect(&url));
8909 EXPECT_EQ("http://login.example.com/", url);
8910}
8911
[email protected]4eddbc732012-08-09 05:40:178912// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018913TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498914 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8915 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298916
8917 HttpRequestInfo request;
8918 request.method = "GET";
bncce36dca22015-04-21 22:11:238919 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108920 request.traffic_annotation =
8921 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298922
8923 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178924 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8925 "Host: www.example.org:443\r\n"
8926 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298927 };
8928
8929 MockRead data_reads[] = {
8930 MockRead("HTTP/1.1 404 Not Found\r\n"),
8931 MockRead("Content-Length: 23\r\n\r\n"),
8932 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068933 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298934 };
8935
8936 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8937 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068938 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298939
[email protected]bb88e1d32013-05-03 23:11:078940 session_deps_.socket_factory->AddSocketDataProvider(&data);
8941 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298942
[email protected]49639fa2011-12-20 23:22:418943 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298944
danakj1fd259a02016-04-16 03:17:098945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298947
tfarina42834112016-09-22 13:38:208948 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018949 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298950
8951 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018952 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298953
ttuttle960fcbf2016-04-19 13:26:328954 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298955}
8956
[email protected]4eddbc732012-08-09 05:40:178957// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018958TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498959 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8960 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298961
8962 HttpRequestInfo request;
8963 request.method = "GET";
bncce36dca22015-04-21 22:11:238964 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108965 request.traffic_annotation =
8966 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298967
bncdf80d44fd2016-07-15 20:27:418968 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238969 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418970 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088971 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298972 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418973 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298974 };
8975
8976 static const char* const kExtraHeaders[] = {
8977 "location",
8978 "http://login.example.com/",
8979 };
bnc42331402016-07-25 13:36:158980 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238981 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Bence Békyd74f4382018-02-20 18:26:198982 SpdySerializedFrame body(
8983 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298984 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418985 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138986 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298987 };
8988
rch8e6c6c42015-05-01 14:05:138989 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8990 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068991 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368992 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298993
[email protected]bb88e1d32013-05-03 23:11:078994 session_deps_.socket_factory->AddSocketDataProvider(&data);
8995 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298996
[email protected]49639fa2011-12-20 23:22:418997 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298998
danakj1fd259a02016-04-16 03:17:098999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299001
tfarina42834112016-09-22 13:38:209002 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299004
9005 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019006 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299007
ttuttle960fcbf2016-04-19 13:26:329008 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299009}
9010
[email protected]0c5fb722012-02-28 11:50:359011// Test the request-challenge-retry sequence for basic auth, through
9012// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019013TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359014 HttpRequestInfo request;
9015 request.method = "GET";
bncce36dca22015-04-21 22:11:239016 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359017 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299018 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109019 request.traffic_annotation =
9020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359021
9022 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599023 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499024 ProxyResolutionService::CreateFixedFromPacResult(
9025 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519026 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079027 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359029
9030 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:419031 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239032 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:419033 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:089034 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389035 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359036
bnc691fda62016-08-12 00:43:169037 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359038 // be issuing -- the final header line contains the credentials.
9039 const char* const kAuthCredentials[] = {
9040 "proxy-authorization", "Basic Zm9vOmJhcg==",
9041 };
bncdf80d44fd2016-07-15 20:27:419042 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:349043 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:239044 HostPortPair("www.example.org", 443)));
9045 // fetch https://www.example.org/ via HTTP
9046 const char get[] =
9047 "GET / HTTP/1.1\r\n"
9048 "Host: www.example.org\r\n"
9049 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:419050 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199051 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359052
9053 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419054 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9055 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359056 };
9057
9058 // The proxy responds to the connect with a 407, using a persistent
9059 // connection.
thestig9d3bb0c2015-01-24 00:49:519060 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359061 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359062 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9063 };
bnc42331402016-07-25 13:36:159064 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:419065 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359066
bnc42331402016-07-25 13:36:159067 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359068 const char resp[] = "HTTP/1.1 200 OK\r\n"
9069 "Content-Length: 5\r\n\r\n";
9070
bncdf80d44fd2016-07-15 20:27:419071 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199072 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
bncdf80d44fd2016-07-15 20:27:419073 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199074 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359075 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419076 CreateMockRead(conn_auth_resp, 1, ASYNC),
9077 CreateMockRead(conn_resp, 4, ASYNC),
9078 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9079 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139080 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359081 };
9082
rch8e6c6c42015-05-01 14:05:139083 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9084 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079085 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359086 // Negotiate SPDY to the proxy
9087 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369088 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079089 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359090 // Vanilla SSL to the server
9091 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079092 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359093
9094 TestCompletionCallback callback1;
9095
bnc87dcefc2017-05-25 12:47:589096 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199097 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359098
9099 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019100 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359101
9102 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019103 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469104 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359105 log.GetEntries(&entries);
9106 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009107 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9108 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359109 ExpectLogContainsSomewhere(
9110 entries, pos,
mikecirone8b85c432016-09-08 19:11:009111 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9112 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359113
9114 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529115 ASSERT_TRUE(response);
9116 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359117 EXPECT_EQ(407, response->headers->response_code());
9118 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529119 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439120 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359121
9122 TestCompletionCallback callback2;
9123
9124 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9125 callback2.callback());
robpercival214763f2016-07-01 23:27:019126 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359127
9128 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019129 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359130
9131 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529132 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359133
9134 EXPECT_TRUE(response->headers->IsKeepAlive());
9135 EXPECT_EQ(200, response->headers->response_code());
9136 EXPECT_EQ(5, response->headers->GetContentLength());
9137 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9138
9139 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529140 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359141
[email protected]029c83b62013-01-24 05:28:209142 LoadTimingInfo load_timing_info;
9143 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9144 TestLoadTimingNotReusedWithPac(load_timing_info,
9145 CONNECT_TIMING_HAS_SSL_TIMES);
9146
[email protected]0c5fb722012-02-28 11:50:359147 trans.reset();
9148 session->CloseAllConnections();
9149}
9150
[email protected]7c6f7ba2012-04-03 04:09:299151// Test that an explicitly trusted SPDY proxy can push a resource from an
9152// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019153TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159154 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199155 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159156 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9157 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299158 HttpRequestInfo request;
9159 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109160 request.traffic_annotation =
9161 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299162
[email protected]7c6f7ba2012-04-03 04:09:299163 request.method = "GET";
bncce36dca22015-04-21 22:11:239164 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299165 push_request.method = "GET";
9166 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109167 push_request.traffic_annotation =
9168 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299169
tbansal28e68f82016-02-04 02:56:159170 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599171 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499172 ProxyResolutionService::CreateFixedFromPacResult(
9173 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519174 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079175 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509176
inlinechan894515af2016-12-09 02:40:109177 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509178
danakj1fd259a02016-04-16 03:17:099179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299180
bncdf80d44fd2016-07-15 20:27:419181 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459182 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359183 SpdySerializedFrame stream2_priority(
9184 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299185
9186 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419187 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359188 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299189 };
9190
Bence Béky7bf94362018-01-10 13:19:369191 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9192 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9193
bncdf80d44fd2016-07-15 20:27:419194 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159195 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299196
bncdf80d44fd2016-07-15 20:27:419197 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299198
Bence Békyd74f4382018-02-20 18:26:199199 SpdySerializedFrame stream2_body(
9200 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299201
9202 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369203 CreateMockRead(stream2_syn, 1, ASYNC),
9204 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359205 CreateMockRead(stream1_body, 4, ASYNC),
9206 CreateMockRead(stream2_body, 5, ASYNC),
9207 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299208 };
9209
rch8e6c6c42015-05-01 14:05:139210 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9211 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079212 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299213 // Negotiate SPDY to the proxy
9214 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369215 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079216 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299217
bnc87dcefc2017-05-25 12:47:589218 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199219 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299220 TestCompletionCallback callback;
9221 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019222 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299223
9224 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019225 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299226 const HttpResponseInfo* response = trans->GetResponseInfo();
9227
bnc87dcefc2017-05-25 12:47:589228 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199229 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509230 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019231 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299232
9233 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019234 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299235 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9236
wezca1070932016-05-26 20:30:529237 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299238 EXPECT_TRUE(response->headers->IsKeepAlive());
9239
9240 EXPECT_EQ(200, response->headers->response_code());
9241 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9242
9243 std::string response_data;
9244 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019245 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299246 EXPECT_EQ("hello!", response_data);
9247
[email protected]029c83b62013-01-24 05:28:209248 LoadTimingInfo load_timing_info;
9249 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9250 TestLoadTimingNotReusedWithPac(load_timing_info,
9251 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9252
[email protected]7c6f7ba2012-04-03 04:09:299253 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529254 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299255 EXPECT_EQ(200, push_response->headers->response_code());
9256
9257 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019258 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299259 EXPECT_EQ("pushed", response_data);
9260
[email protected]029c83b62013-01-24 05:28:209261 LoadTimingInfo push_load_timing_info;
9262 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9263 TestLoadTimingReusedWithPac(push_load_timing_info);
9264 // The transactions should share a socket ID, despite being for different
9265 // origins.
9266 EXPECT_EQ(load_timing_info.socket_log_id,
9267 push_load_timing_info.socket_log_id);
9268
[email protected]7c6f7ba2012-04-03 04:09:299269 trans.reset();
9270 push_trans.reset();
9271 session->CloseAllConnections();
9272}
9273
[email protected]8c843192012-04-05 07:15:009274// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019275TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159276 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199277 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159278 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9279 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009280 HttpRequestInfo request;
9281
9282 request.method = "GET";
bncce36dca22015-04-21 22:11:239283 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109284 request.traffic_annotation =
9285 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009286
Ramin Halavatica8d5252018-03-12 05:33:499287 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9288 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519289 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079290 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509291
9292 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109293 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509294
danakj1fd259a02016-04-16 03:17:099295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009296
bncdf80d44fd2016-07-15 20:27:419297 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459298 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009299
bncdf80d44fd2016-07-15 20:27:419300 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089301 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009302
9303 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419304 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009305 };
9306
bncdf80d44fd2016-07-15 20:27:419307 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159308 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009309
bncdf80d44fd2016-07-15 20:27:419310 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009311
bncdf80d44fd2016-07-15 20:27:419312 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559313 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009314
9315 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419316 CreateMockRead(stream1_reply, 1, ASYNC),
9317 CreateMockRead(stream2_syn, 2, ASYNC),
9318 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599319 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009320 };
9321
rch8e6c6c42015-05-01 14:05:139322 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9323 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079324 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009325 // Negotiate SPDY to the proxy
9326 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369327 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079328 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009329
bnc87dcefc2017-05-25 12:47:589330 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199331 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009332 TestCompletionCallback callback;
9333 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009335
9336 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019337 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009338 const HttpResponseInfo* response = trans->GetResponseInfo();
9339
wezca1070932016-05-26 20:30:529340 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009341 EXPECT_TRUE(response->headers->IsKeepAlive());
9342
9343 EXPECT_EQ(200, response->headers->response_code());
9344 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9345
9346 std::string response_data;
9347 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019348 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009349 EXPECT_EQ("hello!", response_data);
9350
9351 trans.reset();
9352 session->CloseAllConnections();
9353}
9354
tbansal8ef1d3e2016-02-03 04:05:429355// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9356// resources.
bncd16676a2016-07-20 16:23:019357TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159358 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199359 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159360 proxy_delegate->set_trusted_spdy_proxy(
9361 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9362
tbansal8ef1d3e2016-02-03 04:05:429363 HttpRequestInfo request;
9364
9365 request.method = "GET";
9366 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109367 request.traffic_annotation =
9368 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429369
9370 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499371 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9372 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429373 BoundTestNetLog log;
9374 session_deps_.net_log = log.bound().net_log();
9375
9376 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109377 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429378
danakj1fd259a02016-04-16 03:17:099379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429380
bncdf80d44fd2016-07-15 20:27:419381 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459382 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359383 SpdySerializedFrame stream2_priority(
9384 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429385
9386 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419387 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359388 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429389 };
9390
bncdf80d44fd2016-07-15 20:27:419391 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159392 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429393
bncdf80d44fd2016-07-15 20:27:419394 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339395 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499396
bncdf80d44fd2016-07-15 20:27:419397 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429398
bncdf80d44fd2016-07-15 20:27:419399 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159400 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429401
bncdf80d44fd2016-07-15 20:27:419402 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429403
9404 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419405 CreateMockRead(stream1_reply, 1, ASYNC),
9406 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359407 CreateMockRead(stream1_body, 4, ASYNC),
9408 CreateMockRead(stream2_body, 5, ASYNC),
9409 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429410 };
9411
9412 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9413 arraysize(spdy_writes));
9414 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9415 // Negotiate SPDY to the proxy
9416 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369417 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429418 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9419
bnc87dcefc2017-05-25 12:47:589420 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199421 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429422 TestCompletionCallback callback;
9423 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429425
9426 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019427 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429428 const HttpResponseInfo* response = trans->GetResponseInfo();
9429
wezca1070932016-05-26 20:30:529430 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429431 EXPECT_TRUE(response->headers->IsKeepAlive());
9432
9433 EXPECT_EQ(200, response->headers->response_code());
9434 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9435
9436 std::string response_data;
9437 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019438 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429439 EXPECT_EQ("hello!", response_data);
9440
9441 trans.reset();
9442 session->CloseAllConnections();
9443}
9444
[email protected]2df19bb2010-08-25 20:13:469445// Test HTTPS connections to a site with a bad certificate, going through an
9446// HTTPS proxy
bncd16676a2016-07-20 16:23:019447TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499448 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9449 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469450
9451 HttpRequestInfo request;
9452 request.method = "GET";
bncce36dca22015-04-21 22:11:239453 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109454 request.traffic_annotation =
9455 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469456
9457 // Attempt to fetch the URL from a server with a bad cert
9458 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179459 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9460 "Host: www.example.org:443\r\n"
9461 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469462 };
9463
9464 MockRead bad_cert_reads[] = {
9465 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069466 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469467 };
9468
9469 // Attempt to fetch the URL with a good cert
9470 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179471 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9472 "Host: www.example.org:443\r\n"
9473 "Proxy-Connection: keep-alive\r\n\r\n"),
9474 MockWrite("GET / HTTP/1.1\r\n"
9475 "Host: www.example.org\r\n"
9476 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469477 };
9478
9479 MockRead good_cert_reads[] = {
9480 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9481 MockRead("HTTP/1.0 200 OK\r\n"),
9482 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9483 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069484 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469485 };
9486
9487 StaticSocketDataProvider ssl_bad_certificate(
9488 bad_cert_reads, arraysize(bad_cert_reads),
9489 bad_cert_writes, arraysize(bad_cert_writes));
9490 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9491 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069492 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9493 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469494
9495 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9497 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469499
9500 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9502 session_deps_.socket_factory->AddSocketDataProvider(&data);
9503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469504
[email protected]49639fa2011-12-20 23:22:419505 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469506
danakj1fd259a02016-04-16 03:17:099507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469509
tfarina42834112016-09-22 13:38:209510 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019511 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469512
9513 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019514 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469515
bnc691fda62016-08-12 00:43:169516 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469518
9519 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019520 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469521
bnc691fda62016-08-12 00:43:169522 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469523
wezca1070932016-05-26 20:30:529524 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469525 EXPECT_EQ(100, response->headers->GetContentLength());
9526}
9527
bncd16676a2016-07-20 16:23:019528TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429529 HttpRequestInfo request;
9530 request.method = "GET";
bncce36dca22015-04-21 22:11:239531 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439532 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9533 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109534 request.traffic_annotation =
9535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429536
danakj1fd259a02016-04-16 03:17:099537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279539
[email protected]1c773ea12009-04-28 19:58:429540 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239541 MockWrite(
9542 "GET / HTTP/1.1\r\n"
9543 "Host: www.example.org\r\n"
9544 "Connection: keep-alive\r\n"
9545 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429546 };
9547
9548 // Lastly, the server responds with the actual content.
9549 MockRead data_reads[] = {
9550 MockRead("HTTP/1.0 200 OK\r\n"),
9551 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9552 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069553 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429554 };
9555
[email protected]31a2bfe2010-02-09 08:03:399556 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9557 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079558 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429559
[email protected]49639fa2011-12-20 23:22:419560 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429561
tfarina42834112016-09-22 13:38:209562 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429564
9565 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019566 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429567}
9568
bncd16676a2016-07-20 16:23:019569TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299570 HttpRequestInfo request;
9571 request.method = "GET";
bncce36dca22015-04-21 22:11:239572 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299573 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9574 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109575 request.traffic_annotation =
9576 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299577
Ramin Halavatica8d5252018-03-12 05:33:499578 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9579 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279582
[email protected]da81f132010-08-18 23:39:299583 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179584 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9585 "Host: www.example.org:443\r\n"
9586 "Proxy-Connection: keep-alive\r\n"
9587 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299588 };
9589 MockRead data_reads[] = {
9590 // Return an error, so the transaction stops here (this test isn't
9591 // interested in the rest).
9592 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9593 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9594 MockRead("Proxy-Connection: close\r\n\r\n"),
9595 };
9596
9597 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9598 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079599 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299600
[email protected]49639fa2011-12-20 23:22:419601 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299602
tfarina42834112016-09-22 13:38:209603 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299605
9606 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019607 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299608}
9609
bncd16676a2016-07-20 16:23:019610TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429611 HttpRequestInfo request;
9612 request.method = "GET";
bncce36dca22015-04-21 22:11:239613 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169614 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9615 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:109616 request.traffic_annotation =
9617 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429618
danakj1fd259a02016-04-16 03:17:099619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169620 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279621
[email protected]1c773ea12009-04-28 19:58:429622 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239623 MockWrite(
9624 "GET / HTTP/1.1\r\n"
9625 "Host: www.example.org\r\n"
9626 "Connection: keep-alive\r\n"
9627 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429628 };
9629
9630 // Lastly, the server responds with the actual content.
9631 MockRead data_reads[] = {
9632 MockRead("HTTP/1.0 200 OK\r\n"),
9633 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9634 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069635 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429636 };
9637
[email protected]31a2bfe2010-02-09 08:03:399638 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9639 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429641
[email protected]49639fa2011-12-20 23:22:419642 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429643
tfarina42834112016-09-22 13:38:209644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429646
9647 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019648 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429649}
9650
bncd16676a2016-07-20 16:23:019651TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429652 HttpRequestInfo request;
9653 request.method = "POST";
bncce36dca22015-04-21 22:11:239654 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109655 request.traffic_annotation =
9656 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429657
danakj1fd259a02016-04-16 03:17:099658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279660
[email protected]1c773ea12009-04-28 19:58:429661 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239662 MockWrite(
9663 "POST / HTTP/1.1\r\n"
9664 "Host: www.example.org\r\n"
9665 "Connection: keep-alive\r\n"
9666 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429667 };
9668
9669 // Lastly, the server responds with the actual content.
9670 MockRead data_reads[] = {
9671 MockRead("HTTP/1.0 200 OK\r\n"),
9672 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9673 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069674 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429675 };
9676
[email protected]31a2bfe2010-02-09 08:03:399677 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9678 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079679 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429680
[email protected]49639fa2011-12-20 23:22:419681 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429682
tfarina42834112016-09-22 13:38:209683 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429685
9686 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019687 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429688}
9689
bncd16676a2016-07-20 16:23:019690TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429691 HttpRequestInfo request;
9692 request.method = "PUT";
bncce36dca22015-04-21 22:11:239693 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109694 request.traffic_annotation =
9695 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429696
danakj1fd259a02016-04-16 03:17:099697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169698 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279699
[email protected]1c773ea12009-04-28 19:58:429700 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239701 MockWrite(
9702 "PUT / HTTP/1.1\r\n"
9703 "Host: www.example.org\r\n"
9704 "Connection: keep-alive\r\n"
9705 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429706 };
9707
9708 // Lastly, the server responds with the actual content.
9709 MockRead data_reads[] = {
9710 MockRead("HTTP/1.0 200 OK\r\n"),
9711 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9712 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069713 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429714 };
9715
[email protected]31a2bfe2010-02-09 08:03:399716 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9717 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079718 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429719
[email protected]49639fa2011-12-20 23:22:419720 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429721
tfarina42834112016-09-22 13:38:209722 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429724
9725 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019726 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429727}
9728
bncd16676a2016-07-20 16:23:019729TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429730 HttpRequestInfo request;
9731 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239732 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109733 request.traffic_annotation =
9734 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429735
danakj1fd259a02016-04-16 03:17:099736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279738
[email protected]1c773ea12009-04-28 19:58:429739 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139740 MockWrite("HEAD / HTTP/1.1\r\n"
9741 "Host: www.example.org\r\n"
9742 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429743 };
9744
9745 // Lastly, the server responds with the actual content.
9746 MockRead data_reads[] = {
9747 MockRead("HTTP/1.0 200 OK\r\n"),
9748 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9749 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069750 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429751 };
9752
[email protected]31a2bfe2010-02-09 08:03:399753 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9754 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079755 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429756
[email protected]49639fa2011-12-20 23:22:419757 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429758
tfarina42834112016-09-22 13:38:209759 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429761
9762 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019763 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429764}
9765
bncd16676a2016-07-20 16:23:019766TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429767 HttpRequestInfo request;
9768 request.method = "GET";
bncce36dca22015-04-21 22:11:239769 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429770 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109771 request.traffic_annotation =
9772 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429773
danakj1fd259a02016-04-16 03:17:099774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169775 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279776
[email protected]1c773ea12009-04-28 19:58:429777 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239778 MockWrite(
9779 "GET / HTTP/1.1\r\n"
9780 "Host: www.example.org\r\n"
9781 "Connection: keep-alive\r\n"
9782 "Pragma: no-cache\r\n"
9783 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429784 };
9785
9786 // Lastly, the server responds with the actual content.
9787 MockRead data_reads[] = {
9788 MockRead("HTTP/1.0 200 OK\r\n"),
9789 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9790 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069791 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429792 };
9793
[email protected]31a2bfe2010-02-09 08:03:399794 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9795 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079796 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429797
[email protected]49639fa2011-12-20 23:22:419798 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429799
tfarina42834112016-09-22 13:38:209800 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429802
9803 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019804 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429805}
9806
bncd16676a2016-07-20 16:23:019807TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429808 HttpRequestInfo request;
9809 request.method = "GET";
bncce36dca22015-04-21 22:11:239810 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429811 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109812 request.traffic_annotation =
9813 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429814
danakj1fd259a02016-04-16 03:17:099815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279817
[email protected]1c773ea12009-04-28 19:58:429818 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239819 MockWrite(
9820 "GET / HTTP/1.1\r\n"
9821 "Host: www.example.org\r\n"
9822 "Connection: keep-alive\r\n"
9823 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429824 };
9825
9826 // Lastly, the server responds with the actual content.
9827 MockRead data_reads[] = {
9828 MockRead("HTTP/1.0 200 OK\r\n"),
9829 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9830 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069831 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429832 };
9833
[email protected]31a2bfe2010-02-09 08:03:399834 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9835 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079836 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429837
[email protected]49639fa2011-12-20 23:22:419838 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429839
tfarina42834112016-09-22 13:38:209840 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429842
9843 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019844 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429845}
9846
bncd16676a2016-07-20 16:23:019847TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429848 HttpRequestInfo request;
9849 request.method = "GET";
bncce36dca22015-04-21 22:11:239850 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439851 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:109852 request.traffic_annotation =
9853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429854
danakj1fd259a02016-04-16 03:17:099855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279857
[email protected]1c773ea12009-04-28 19:58:429858 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239859 MockWrite(
9860 "GET / HTTP/1.1\r\n"
9861 "Host: www.example.org\r\n"
9862 "Connection: keep-alive\r\n"
9863 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429864 };
9865
9866 // Lastly, the server responds with the actual content.
9867 MockRead data_reads[] = {
9868 MockRead("HTTP/1.0 200 OK\r\n"),
9869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9870 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069871 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429872 };
9873
[email protected]31a2bfe2010-02-09 08:03:399874 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9875 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079876 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429877
[email protected]49639fa2011-12-20 23:22:419878 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429879
tfarina42834112016-09-22 13:38:209880 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429882
9883 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019884 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429885}
9886
bncd16676a2016-07-20 16:23:019887TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479888 HttpRequestInfo request;
9889 request.method = "GET";
bncce36dca22015-04-21 22:11:239890 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439891 request.extra_headers.SetHeader("referer", "www.foo.com");
9892 request.extra_headers.SetHeader("hEllo", "Kitty");
9893 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:109894 request.traffic_annotation =
9895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479896
danakj1fd259a02016-04-16 03:17:099897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279899
[email protected]270c6412010-03-29 22:02:479900 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239901 MockWrite(
9902 "GET / HTTP/1.1\r\n"
9903 "Host: www.example.org\r\n"
9904 "Connection: keep-alive\r\n"
9905 "referer: www.foo.com\r\n"
9906 "hEllo: Kitty\r\n"
9907 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479908 };
9909
9910 // Lastly, the server responds with the actual content.
9911 MockRead data_reads[] = {
9912 MockRead("HTTP/1.0 200 OK\r\n"),
9913 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9914 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069915 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479916 };
9917
9918 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9919 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079920 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479921
[email protected]49639fa2011-12-20 23:22:419922 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479923
tfarina42834112016-09-22 13:38:209924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479926
9927 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019928 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479929}
9930
bncd16676a2016-07-20 16:23:019931TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279932 HttpRequestInfo request;
9933 request.method = "GET";
bncce36dca22015-04-21 22:11:239934 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109935 request.traffic_annotation =
9936 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279937
Lily Houghton8c2f97d2018-01-22 05:06:599938 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499939 ProxyResolutionService::CreateFixedFromPacResult(
9940 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519941 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079942 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029943
danakj1fd259a02016-04-16 03:17:099944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029946
[email protected]3cd17242009-06-23 02:59:029947 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9948 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9949
9950 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239951 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9952 MockWrite(
9953 "GET / HTTP/1.1\r\n"
9954 "Host: www.example.org\r\n"
9955 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029956
9957 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069958 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029959 MockRead("HTTP/1.0 200 OK\r\n"),
9960 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9961 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069962 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029963 };
9964
[email protected]31a2bfe2010-02-09 08:03:399965 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9966 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079967 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029968
[email protected]49639fa2011-12-20 23:22:419969 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029970
tfarina42834112016-09-22 13:38:209971 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029973
9974 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019975 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029976
bnc691fda62016-08-12 00:43:169977 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529978 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029979
tbansal2ecbbc72016-10-06 17:15:479980 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209981 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169982 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209983 TestLoadTimingNotReusedWithPac(load_timing_info,
9984 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9985
[email protected]3cd17242009-06-23 02:59:029986 std::string response_text;
bnc691fda62016-08-12 00:43:169987 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019988 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029989 EXPECT_EQ("Payload", response_text);
9990}
9991
bncd16676a2016-07-20 16:23:019992TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279993 HttpRequestInfo request;
9994 request.method = "GET";
bncce36dca22015-04-21 22:11:239995 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109996 request.traffic_annotation =
9997 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279998
Lily Houghton8c2f97d2018-01-22 05:06:599999 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910000 ProxyResolutionService::CreateFixedFromPacResult(
10001 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110002 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710003 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210004
danakj1fd259a02016-04-16 03:17:0910005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610006 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210007
[email protected]3cd17242009-06-23 02:59:0210008 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10009 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10010
10011 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310012 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
10013 arraysize(write_buffer)),
10014 MockWrite(
10015 "GET / HTTP/1.1\r\n"
10016 "Host: www.example.org\r\n"
10017 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210018
10019 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110020 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10021 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:3510022 MockRead("HTTP/1.0 200 OK\r\n"),
10023 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10024 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610025 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510026 };
10027
[email protected]31a2bfe2010-02-09 08:03:3910028 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10029 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710030 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510031
[email protected]8ddf8322012-02-23 18:08:0610032 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710033 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510034
[email protected]49639fa2011-12-20 23:22:4110035 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510036
tfarina42834112016-09-22 13:38:2010037 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510039
10040 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110041 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510042
[email protected]029c83b62013-01-24 05:28:2010043 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610044 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010045 TestLoadTimingNotReusedWithPac(load_timing_info,
10046 CONNECT_TIMING_HAS_SSL_TIMES);
10047
bnc691fda62016-08-12 00:43:1610048 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210049 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710050 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510051
10052 std::string response_text;
bnc691fda62016-08-12 00:43:1610053 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110054 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510055 EXPECT_EQ("Payload", response_text);
10056}
10057
bncd16676a2016-07-20 16:23:0110058TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010059 HttpRequestInfo request;
10060 request.method = "GET";
bncce36dca22015-04-21 22:11:2310061 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010062 request.traffic_annotation =
10063 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010064
Ramin Halavatica8d5252018-03-12 05:33:4910065 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10066 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110067 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710068 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010069
danakj1fd259a02016-04-16 03:17:0910070 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010072
10073 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10074 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10075
10076 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310077 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
10078 MockWrite(
10079 "GET / HTTP/1.1\r\n"
10080 "Host: www.example.org\r\n"
10081 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010082
10083 MockRead data_reads[] = {
10084 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
10085 MockRead("HTTP/1.0 200 OK\r\n"),
10086 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10087 MockRead("Payload"),
10088 MockRead(SYNCHRONOUS, OK)
10089 };
10090
10091 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10092 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710093 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010094
10095 TestCompletionCallback callback;
10096
tfarina42834112016-09-22 13:38:2010097 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010099
10100 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110101 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010102
bnc691fda62016-08-12 00:43:1610103 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210104 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010105
10106 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610107 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010108 TestLoadTimingNotReused(load_timing_info,
10109 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10110
10111 std::string response_text;
bnc691fda62016-08-12 00:43:1610112 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110113 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010114 EXPECT_EQ("Payload", response_text);
10115}
10116
bncd16676a2016-07-20 16:23:0110117TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710118 HttpRequestInfo request;
10119 request.method = "GET";
bncce36dca22015-04-21 22:11:2310120 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010121 request.traffic_annotation =
10122 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710123
Lily Houghton8c2f97d2018-01-22 05:06:5910124 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910125 ProxyResolutionService::CreateFixedFromPacResult(
10126 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110127 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710128 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510129
danakj1fd259a02016-04-16 03:17:0910130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510132
[email protected]e0c27be2009-07-15 13:09:3510133 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10134 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710135 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310136 0x05, // Version
10137 0x01, // Command (CONNECT)
10138 0x00, // Reserved.
10139 0x03, // Address type (DOMAINNAME).
10140 0x0F, // Length of domain (15)
10141 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10142 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710143 };
[email protected]e0c27be2009-07-15 13:09:3510144 const char kSOCKS5OkResponse[] =
10145 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10146
10147 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310148 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10149 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10150 MockWrite(
10151 "GET / HTTP/1.1\r\n"
10152 "Host: www.example.org\r\n"
10153 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510154
10155 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110156 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10157 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510158 MockRead("HTTP/1.0 200 OK\r\n"),
10159 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10160 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610161 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510162 };
10163
[email protected]31a2bfe2010-02-09 08:03:3910164 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10165 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710166 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510167
[email protected]49639fa2011-12-20 23:22:4110168 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510169
tfarina42834112016-09-22 13:38:2010170 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510172
10173 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110174 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510175
bnc691fda62016-08-12 00:43:1610176 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210177 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710178 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510179
[email protected]029c83b62013-01-24 05:28:2010180 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610181 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010182 TestLoadTimingNotReusedWithPac(load_timing_info,
10183 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10184
[email protected]e0c27be2009-07-15 13:09:3510185 std::string response_text;
bnc691fda62016-08-12 00:43:1610186 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110187 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510188 EXPECT_EQ("Payload", response_text);
10189}
10190
bncd16676a2016-07-20 16:23:0110191TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710192 HttpRequestInfo request;
10193 request.method = "GET";
bncce36dca22015-04-21 22:11:2310194 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010195 request.traffic_annotation =
10196 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710197
Lily Houghton8c2f97d2018-01-22 05:06:5910198 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910199 ProxyResolutionService::CreateFixedFromPacResult(
10200 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110201 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710202 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510203
danakj1fd259a02016-04-16 03:17:0910204 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610205 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510206
[email protected]e0c27be2009-07-15 13:09:3510207 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10208 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710209 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310210 0x05, // Version
10211 0x01, // Command (CONNECT)
10212 0x00, // Reserved.
10213 0x03, // Address type (DOMAINNAME).
10214 0x0F, // Length of domain (15)
10215 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10216 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710217 };
10218
[email protected]e0c27be2009-07-15 13:09:3510219 const char kSOCKS5OkResponse[] =
10220 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10221
10222 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310223 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10224 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10225 arraysize(kSOCKS5OkRequest)),
10226 MockWrite(
10227 "GET / HTTP/1.1\r\n"
10228 "Host: www.example.org\r\n"
10229 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510230
10231 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110232 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10233 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210234 MockRead("HTTP/1.0 200 OK\r\n"),
10235 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10236 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610237 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210238 };
10239
[email protected]31a2bfe2010-02-09 08:03:3910240 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10241 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710242 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210243
[email protected]8ddf8322012-02-23 18:08:0610244 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210246
[email protected]49639fa2011-12-20 23:22:4110247 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210248
tfarina42834112016-09-22 13:38:2010249 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210251
10252 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110253 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210254
bnc691fda62016-08-12 00:43:1610255 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210256 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710257 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210258
[email protected]029c83b62013-01-24 05:28:2010259 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610260 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010261 TestLoadTimingNotReusedWithPac(load_timing_info,
10262 CONNECT_TIMING_HAS_SSL_TIMES);
10263
[email protected]3cd17242009-06-23 02:59:0210264 std::string response_text;
bnc691fda62016-08-12 00:43:1610265 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110266 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210267 EXPECT_EQ("Payload", response_text);
10268}
10269
[email protected]448d4ca52012-03-04 04:12:2310270namespace {
10271
[email protected]04e5be32009-06-26 20:00:3110272// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610273
10274struct GroupNameTest {
10275 std::string proxy_server;
10276 std::string url;
10277 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810278 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610279};
10280
danakj1fd259a02016-04-16 03:17:0910281std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710282 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910283 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610284
bnc525e175a2016-06-20 12:36:4010285 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310286 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110287 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210288 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110289 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210290 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610291 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610292
10293 return session;
10294}
10295
mmenkee65e7af2015-10-13 17:16:4210296int GroupNameTransactionHelper(const std::string& url,
10297 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610298 HttpRequestInfo request;
10299 request.method = "GET";
10300 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1010301 request.traffic_annotation =
10302 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610303
bnc691fda62016-08-12 00:43:1610304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710305
[email protected]49639fa2011-12-20 23:22:4110306 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610307
10308 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010309 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610310}
10311
[email protected]448d4ca52012-03-04 04:12:2310312} // namespace
10313
bncd16676a2016-07-20 16:23:0110314TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610315 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310316 {
10317 "", // unused
10318 "http://www.example.org/direct",
10319 "www.example.org:80",
10320 false,
10321 },
10322 {
10323 "", // unused
10324 "http://[2001:1418:13:1::25]/direct",
10325 "[2001:1418:13:1::25]:80",
10326 false,
10327 },
[email protected]04e5be32009-06-26 20:00:3110328
bncce36dca22015-04-21 22:11:2310329 // SSL Tests
10330 {
10331 "", // unused
10332 "https://www.example.org/direct_ssl",
10333 "ssl/www.example.org:443",
10334 true,
10335 },
10336 {
10337 "", // unused
10338 "https://[2001:1418:13:1::25]/direct",
10339 "ssl/[2001:1418:13:1::25]:443",
10340 true,
10341 },
10342 {
10343 "", // unused
bncaa60ff402016-06-22 19:12:4210344 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310345 "ssl/host.with.alternate:443",
10346 true,
10347 },
[email protected]2d731a32010-04-29 01:04:0610348 };
[email protected]2ff8b312010-04-26 22:20:5410349
viettrungluue4a8b882014-10-16 06:17:3810350 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910351 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910352 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10353 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910354 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010355 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610356
mmenkee65e7af2015-10-13 17:16:4210357 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810358 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810359 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310360 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810361 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910362 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210363 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10364 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810365 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610366
10367 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210368 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910369 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810370 EXPECT_EQ(tests[i].expected_group_name,
10371 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910372 } else {
[email protected]e60e47a2010-07-14 03:37:1810373 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810374 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910375 }
10376 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10377 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10378 // When SSL proxy is not in use, socket must be requested from
10379 // |transport_conn_pool|.
10380 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610381 }
[email protected]2d731a32010-04-29 01:04:0610382}
10383
bncd16676a2016-07-20 16:23:0110384TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610385 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310386 {
Matt Menked1eb6d42018-01-17 04:54:0610387 "http_proxy", "http://www.example.org/http_proxy_normal",
10388 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310389 },
[email protected]2d731a32010-04-29 01:04:0610390
bncce36dca22015-04-21 22:11:2310391 // SSL Tests
10392 {
Matt Menked1eb6d42018-01-17 04:54:0610393 "http_proxy", "https://www.example.org/http_connect_ssl",
10394 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310395 },
[email protected]af3490e2010-10-16 21:02:2910396
bncce36dca22015-04-21 22:11:2310397 {
Matt Menked1eb6d42018-01-17 04:54:0610398 "http_proxy", "https://host.with.alternate/direct",
10399 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310400 },
[email protected]45499252013-01-23 17:12:5610401
bncce36dca22015-04-21 22:11:2310402 {
Matt Menked1eb6d42018-01-17 04:54:0610403 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10404 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310405 },
[email protected]2d731a32010-04-29 01:04:0610406 };
10407
viettrungluue4a8b882014-10-16 06:17:3810408 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910409 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910410 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10411 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910412 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010413 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610414
mmenkee65e7af2015-10-13 17:16:4210415 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610416
[email protected]e60e47a2010-07-14 03:37:1810417 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310418 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410419 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310420 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410421 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910422 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910423 mock_pool_manager->SetSocketPoolForHTTPProxy(
10424 proxy_host, base::WrapUnique(http_proxy_pool));
10425 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10426 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810427 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610428
10429 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210430 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810431 if (tests[i].ssl)
10432 EXPECT_EQ(tests[i].expected_group_name,
10433 ssl_conn_pool->last_group_name_received());
10434 else
10435 EXPECT_EQ(tests[i].expected_group_name,
10436 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610437 }
[email protected]2d731a32010-04-29 01:04:0610438}
10439
bncd16676a2016-07-20 16:23:0110440TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610441 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310442 {
10443 "socks4://socks_proxy:1080",
10444 "http://www.example.org/socks4_direct",
10445 "socks4/www.example.org:80",
10446 false,
10447 },
10448 {
10449 "socks5://socks_proxy:1080",
10450 "http://www.example.org/socks5_direct",
10451 "socks5/www.example.org:80",
10452 false,
10453 },
[email protected]2d731a32010-04-29 01:04:0610454
bncce36dca22015-04-21 22:11:2310455 // SSL Tests
10456 {
10457 "socks4://socks_proxy:1080",
10458 "https://www.example.org/socks4_ssl",
10459 "socks4/ssl/www.example.org:443",
10460 true,
10461 },
10462 {
10463 "socks5://socks_proxy:1080",
10464 "https://www.example.org/socks5_ssl",
10465 "socks5/ssl/www.example.org:443",
10466 true,
10467 },
[email protected]af3490e2010-10-16 21:02:2910468
bncce36dca22015-04-21 22:11:2310469 {
10470 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210471 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310472 "socks4/ssl/host.with.alternate:443",
10473 true,
10474 },
[email protected]04e5be32009-06-26 20:00:3110475 };
10476
viettrungluue4a8b882014-10-16 06:17:3810477 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910478 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910479 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10480 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910481 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010482 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210483
mmenkee65e7af2015-10-13 17:16:4210484 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110485
[email protected]e60e47a2010-07-14 03:37:1810486 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310487 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410488 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310489 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410490 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910491 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910492 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10493 proxy_host, base::WrapUnique(socks_conn_pool));
10494 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10495 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810496 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110497
bnc691fda62016-08-12 00:43:1610498 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110499
[email protected]2d731a32010-04-29 01:04:0610500 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210501 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810502 if (tests[i].ssl)
10503 EXPECT_EQ(tests[i].expected_group_name,
10504 ssl_conn_pool->last_group_name_received());
10505 else
10506 EXPECT_EQ(tests[i].expected_group_name,
10507 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110508 }
10509}
10510
bncd16676a2016-07-20 16:23:0110511TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710512 HttpRequestInfo request;
10513 request.method = "GET";
bncce36dca22015-04-21 22:11:2310514 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010515 request.traffic_annotation =
10516 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710517
Ramin Halavatica8d5252018-03-12 05:33:4910518 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10519 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210520
[email protected]69719062010-01-05 20:09:2110521 // This simulates failure resolving all hostnames; that means we will fail
10522 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710523 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210524
danakj1fd259a02016-04-16 03:17:0910525 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510527
[email protected]49639fa2011-12-20 23:22:4110528 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510529
tfarina42834112016-09-22 13:38:2010530 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510532
[email protected]9172a982009-06-06 00:30:2510533 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110534 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510535}
10536
Miriam Gershenson2a01b162018-03-22 22:54:4710537// LOAD_BYPASS_CACHE should trigger the host cache bypass.
10538TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2710539 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010540 HttpRequestInfo request_info;
10541 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4710542 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1010543 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010544 request_info.traffic_annotation =
10545 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710546
[email protected]a2c2fb92009-07-18 07:31:0410547 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910548 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210549
danakj1fd259a02016-04-16 03:17:0910550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810552
bncce36dca22015-04-21 22:11:2310553 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810554 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910555 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010556 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710557 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310558 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010559 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010560 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710562 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110563 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810564
10565 // Verify that it was added to host cache, by doing a subsequent async lookup
10566 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010567 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710568 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310569 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010570 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010571 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110572 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810573
bncce36dca22015-04-21 22:11:2310574 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810575 // we can tell if the next lookup hit the cache, or the "network".
10576 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310577 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810578
10579 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10580 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610581 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910582 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710583 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810584
[email protected]3b9cca42009-06-16 01:08:2810585 // Run the request.
tfarina42834112016-09-22 13:38:2010586 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110587 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110588 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810589
10590 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310591 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110592 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810593}
10594
[email protected]0877e3d2009-10-17 22:29:5710595// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110596TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710597 HttpRequestInfo request;
10598 request.method = "GET";
10599 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010600 request.traffic_annotation =
10601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710602
10603 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610604 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710605 };
[email protected]31a2bfe2010-02-09 08:03:3910606 StaticSocketDataProvider data(NULL, 0,
10607 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710608 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710610
[email protected]49639fa2011-12-20 23:22:4110611 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710612
bnc691fda62016-08-12 00:43:1610613 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710614
tfarina42834112016-09-22 13:38:2010615 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710617
10618 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110619 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910620
10621 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610622 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910623 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710624}
10625
zmo9528c9f42015-08-04 22:12:0810626// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110627TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710628 HttpRequestInfo request;
10629 request.method = "GET";
10630 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010631 request.traffic_annotation =
10632 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710633
10634 MockRead data_reads[] = {
10635 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610636 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710637 };
10638
[email protected]31a2bfe2010-02-09 08:03:3910639 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710640 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710642
[email protected]49639fa2011-12-20 23:22:4110643 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710644
bnc691fda62016-08-12 00:43:1610645 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710646
tfarina42834112016-09-22 13:38:2010647 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710649
10650 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110651 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810652
bnc691fda62016-08-12 00:43:1610653 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210654 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810655
wezca1070932016-05-26 20:30:5210656 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810657 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10658
10659 std::string response_data;
bnc691fda62016-08-12 00:43:1610660 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110661 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810662 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910663
10664 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610665 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910666 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710667}
10668
10669// Make sure that a dropped connection while draining the body for auth
10670// restart does the right thing.
bncd16676a2016-07-20 16:23:0110671TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710672 HttpRequestInfo request;
10673 request.method = "GET";
bncce36dca22015-04-21 22:11:2310674 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010675 request.traffic_annotation =
10676 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710677
10678 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310679 MockWrite(
10680 "GET / HTTP/1.1\r\n"
10681 "Host: www.example.org\r\n"
10682 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710683 };
10684
10685 MockRead data_reads1[] = {
10686 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10687 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10688 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10689 MockRead("Content-Length: 14\r\n\r\n"),
10690 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610691 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710692 };
10693
[email protected]31a2bfe2010-02-09 08:03:3910694 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10695 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710696 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710697
bnc691fda62016-08-12 00:43:1610698 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710699 // be issuing -- the final header line contains the credentials.
10700 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310701 MockWrite(
10702 "GET / HTTP/1.1\r\n"
10703 "Host: www.example.org\r\n"
10704 "Connection: keep-alive\r\n"
10705 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710706 };
10707
10708 // Lastly, the server responds with the actual content.
10709 MockRead data_reads2[] = {
10710 MockRead("HTTP/1.1 200 OK\r\n"),
10711 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10712 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610713 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710714 };
10715
[email protected]31a2bfe2010-02-09 08:03:3910716 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10717 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710718 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910719 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710720
[email protected]49639fa2011-12-20 23:22:4110721 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710722
bnc691fda62016-08-12 00:43:1610723 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010724
tfarina42834112016-09-22 13:38:2010725 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710727
10728 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110729 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710730
bnc691fda62016-08-12 00:43:1610731 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210732 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410733 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710734
[email protected]49639fa2011-12-20 23:22:4110735 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710736
bnc691fda62016-08-12 00:43:1610737 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710739
10740 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110741 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710742
bnc691fda62016-08-12 00:43:1610743 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210744 ASSERT_TRUE(response);
10745 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710746 EXPECT_EQ(100, response->headers->GetContentLength());
10747}
10748
10749// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110750TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910751 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10752 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710753
10754 HttpRequestInfo request;
10755 request.method = "GET";
bncce36dca22015-04-21 22:11:2310756 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010757 request.traffic_annotation =
10758 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710759
10760 MockRead proxy_reads[] = {
10761 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610762 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710763 };
10764
[email protected]31a2bfe2010-02-09 08:03:3910765 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610766 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710767
[email protected]bb88e1d32013-05-03 23:11:0710768 session_deps_.socket_factory->AddSocketDataProvider(&data);
10769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710770
[email protected]49639fa2011-12-20 23:22:4110771 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710772
[email protected]bb88e1d32013-05-03 23:11:0710773 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710774
danakj1fd259a02016-04-16 03:17:0910775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710777
tfarina42834112016-09-22 13:38:2010778 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110779 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710780
10781 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110782 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710783}
10784
bncd16676a2016-07-20 16:23:0110785TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610786 HttpRequestInfo request;
10787 request.method = "GET";
bncce36dca22015-04-21 22:11:2310788 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010789 request.traffic_annotation =
10790 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610791
danakj1fd259a02016-04-16 03:17:0910792 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610793 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710794
[email protected]e22e1362009-11-23 21:31:1210795 MockRead data_reads[] = {
10796 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610797 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210798 };
[email protected]9492e4a2010-02-24 00:58:4610799
10800 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710801 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610802
[email protected]49639fa2011-12-20 23:22:4110803 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610804
tfarina42834112016-09-22 13:38:2010805 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610807
robpercival214763f2016-07-01 23:27:0110808 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610809
bnc691fda62016-08-12 00:43:1610810 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210811 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610812
wezca1070932016-05-26 20:30:5210813 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610814 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10815
10816 std::string response_data;
bnc691fda62016-08-12 00:43:1610817 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110818 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210819}
10820
bncd16676a2016-07-20 16:23:0110821TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510822 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210823 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410824 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110825 UploadFileElementReader::ScopedOverridingContentLengthForTests
10826 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310827
danakj1fd259a02016-04-16 03:17:0910828 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910829 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410830 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710831 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210832 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710833
10834 HttpRequestInfo request;
10835 request.method = "POST";
bncce36dca22015-04-21 22:11:2310836 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710837 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010838 request.traffic_annotation =
10839 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710840
danakj1fd259a02016-04-16 03:17:0910841 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610842 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310843
10844 MockRead data_reads[] = {
10845 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10846 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610847 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310848 };
[email protected]31a2bfe2010-02-09 08:03:3910849 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710850 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310851
[email protected]49639fa2011-12-20 23:22:4110852 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310853
tfarina42834112016-09-22 13:38:2010854 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110855 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310856
10857 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110858 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310859
bnc691fda62016-08-12 00:43:1610860 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210861 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310862
maksim.sisove869bf52016-06-23 17:11:5210863 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310864
[email protected]dd3aa792013-07-16 19:10:2310865 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310866}
10867
bncd16676a2016-07-20 16:23:0110868TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510869 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210870 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610871 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810872 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10873 base::WriteFile(temp_file, temp_file_content.c_str(),
10874 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110875 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610876
danakj1fd259a02016-04-16 03:17:0910877 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910878 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410879 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710880 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210881 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710882
10883 HttpRequestInfo request;
10884 request.method = "POST";
bncce36dca22015-04-21 22:11:2310885 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710886 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010887 request.traffic_annotation =
10888 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710889
[email protected]999dd8c2013-11-12 06:45:5410890 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610892 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610893
[email protected]999dd8c2013-11-12 06:45:5410894 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710895 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610896
[email protected]49639fa2011-12-20 23:22:4110897 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610898
tfarina42834112016-09-22 13:38:2010899 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610901
10902 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110903 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610904
[email protected]dd3aa792013-07-16 19:10:2310905 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610906}
10907
bncd16676a2016-07-20 16:23:0110908TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310909 class FakeUploadElementReader : public UploadElementReader {
10910 public:
Chris Watkins7a41d3552017-12-01 02:13:2710911 FakeUploadElementReader() = default;
10912 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310913
Matt Menkecc1d3a902018-02-05 18:27:3310914 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310915
10916 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310917 int Init(CompletionOnceCallback callback) override {
10918 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310919 return ERR_IO_PENDING;
10920 }
avibf0746c2015-12-09 19:53:1410921 uint64_t GetContentLength() const override { return 0; }
10922 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010923 int Read(IOBuffer* buf,
10924 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310925 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310926 return ERR_FAILED;
10927 }
10928
10929 private:
Matt Menkecc1d3a902018-02-05 18:27:3310930 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310931 };
10932
10933 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910934 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10935 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210936 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310937
10938 HttpRequestInfo request;
10939 request.method = "POST";
bncce36dca22015-04-21 22:11:2310940 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310941 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010942 request.traffic_annotation =
10943 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310944
danakj1fd259a02016-04-16 03:17:0910945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810946 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910947 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310948
10949 StaticSocketDataProvider data;
10950 session_deps_.socket_factory->AddSocketDataProvider(&data);
10951
10952 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010953 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510955 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310956
10957 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310958 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10959 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310960
10961 // Return Init()'s result after the transaction gets destroyed.
10962 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310963 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310964}
10965
[email protected]aeefc9e82010-02-19 16:18:2710966// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110967TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710968 HttpRequestInfo request;
10969 request.method = "GET";
bncce36dca22015-04-21 22:11:2310970 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010971 request.traffic_annotation =
10972 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710973
10974 // First transaction will request a resource and receive a Basic challenge
10975 // with realm="first_realm".
10976 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310977 MockWrite(
10978 "GET / HTTP/1.1\r\n"
10979 "Host: www.example.org\r\n"
10980 "Connection: keep-alive\r\n"
10981 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710982 };
10983 MockRead data_reads1[] = {
10984 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10985 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10986 "\r\n"),
10987 };
10988
bnc691fda62016-08-12 00:43:1610989 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710990 // for first_realm. The server will reject and provide a challenge with
10991 // second_realm.
10992 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310993 MockWrite(
10994 "GET / HTTP/1.1\r\n"
10995 "Host: www.example.org\r\n"
10996 "Connection: keep-alive\r\n"
10997 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10998 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710999 };
11000 MockRead data_reads2[] = {
11001 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11002 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11003 "\r\n"),
11004 };
11005
11006 // This again fails, and goes back to first_realm. Make sure that the
11007 // entry is removed from cache.
11008 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311009 MockWrite(
11010 "GET / HTTP/1.1\r\n"
11011 "Host: www.example.org\r\n"
11012 "Connection: keep-alive\r\n"
11013 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11014 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711015 };
11016 MockRead data_reads3[] = {
11017 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11018 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11019 "\r\n"),
11020 };
11021
11022 // Try one last time (with the correct password) and get the resource.
11023 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311024 MockWrite(
11025 "GET / HTTP/1.1\r\n"
11026 "Host: www.example.org\r\n"
11027 "Connection: keep-alive\r\n"
11028 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11029 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711030 };
11031 MockRead data_reads4[] = {
11032 MockRead("HTTP/1.1 200 OK\r\n"
11033 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011034 "Content-Length: 5\r\n"
11035 "\r\n"
11036 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711037 };
11038
11039 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11040 data_writes1, arraysize(data_writes1));
11041 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
11042 data_writes2, arraysize(data_writes2));
11043 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
11044 data_writes3, arraysize(data_writes3));
11045 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
11046 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0711047 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11048 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11049 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11050 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711051
[email protected]49639fa2011-12-20 23:22:4111052 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711053
danakj1fd259a02016-04-16 03:17:0911054 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011056
[email protected]aeefc9e82010-02-19 16:18:2711057 // Issue the first request with Authorize headers. There should be a
11058 // password prompt for first_realm waiting to be filled in after the
11059 // transaction completes.
tfarina42834112016-09-22 13:38:2011060 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711062 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111063 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611064 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211065 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411066 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211067 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411068 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311069 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411070 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911071 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711072
11073 // Issue the second request with an incorrect password. There should be a
11074 // password prompt for second_realm waiting to be filled in after the
11075 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111076 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611077 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11078 callback2.callback());
robpercival214763f2016-07-01 23:27:0111079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711080 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111081 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611082 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211083 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411084 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211085 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411086 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311087 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411088 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911089 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711090
11091 // Issue the third request with another incorrect password. There should be
11092 // a password prompt for first_realm waiting to be filled in. If the password
11093 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11094 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111095 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611096 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11097 callback3.callback());
robpercival214763f2016-07-01 23:27:0111098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711099 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111100 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611101 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211102 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411103 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211104 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411105 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311106 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411107 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911108 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711109
11110 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111111 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611112 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11113 callback4.callback());
robpercival214763f2016-07-01 23:27:0111114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711115 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111116 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611117 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211118 ASSERT_TRUE(response);
11119 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711120}
11121
Bence Béky230ac612017-08-30 19:17:0811122// Regression test for https://crbug.com/754395.
11123TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11124 MockRead data_reads[] = {
11125 MockRead("HTTP/1.1 200 OK\r\n"),
11126 MockRead(kAlternativeServiceHttpHeader),
11127 MockRead("\r\n"),
11128 MockRead("hello world"),
11129 MockRead(SYNCHRONOUS, OK),
11130 };
11131
11132 HttpRequestInfo request;
11133 request.method = "GET";
11134 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011135 request.traffic_annotation =
11136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811137
11138 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11139 session_deps_.socket_factory->AddSocketDataProvider(&data);
11140
11141 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911142 ssl.ssl_info.cert =
11143 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11144 ASSERT_TRUE(ssl.ssl_info.cert);
11145 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11147
11148 TestCompletionCallback callback;
11149
11150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11152
11153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11155
11156 url::SchemeHostPort test_server(request.url);
11157 HttpServerProperties* http_server_properties =
11158 session->http_server_properties();
11159 EXPECT_TRUE(
11160 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11161
11162 EXPECT_THAT(callback.WaitForResult(), IsOk());
11163
11164 const HttpResponseInfo* response = trans.GetResponseInfo();
11165 ASSERT_TRUE(response);
11166 ASSERT_TRUE(response->headers);
11167 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11168 EXPECT_FALSE(response->was_fetched_via_spdy);
11169 EXPECT_FALSE(response->was_alpn_negotiated);
11170
11171 std::string response_data;
11172 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11173 EXPECT_EQ("hello world", response_data);
11174
11175 EXPECT_TRUE(
11176 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11177}
11178
bncd16676a2016-07-20 16:23:0111179TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211180 MockRead data_reads[] = {
11181 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311182 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211183 MockRead("\r\n"),
11184 MockRead("hello world"),
11185 MockRead(SYNCHRONOUS, OK),
11186 };
11187
11188 HttpRequestInfo request;
11189 request.method = "GET";
bncb26024382016-06-29 02:39:4511190 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011191 request.traffic_annotation =
11192 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211193
11194 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211195 session_deps_.socket_factory->AddSocketDataProvider(&data);
11196
bncb26024382016-06-29 02:39:4511197 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911198 ssl.ssl_info.cert =
11199 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11200 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11202
bncc958faa2015-07-31 18:14:5211203 TestCompletionCallback callback;
11204
danakj1fd259a02016-04-16 03:17:0911205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611206 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211207
tfarina42834112016-09-22 13:38:2011208 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211210
bncb26024382016-06-29 02:39:4511211 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011212 HttpServerProperties* http_server_properties =
11213 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411214 EXPECT_TRUE(
11215 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211216
robpercival214763f2016-07-01 23:27:0111217 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211218
bnc691fda62016-08-12 00:43:1611219 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211220 ASSERT_TRUE(response);
11221 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211222 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11223 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211224 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211225
11226 std::string response_data;
bnc691fda62016-08-12 00:43:1611227 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211228 EXPECT_EQ("hello world", response_data);
11229
zhongyic4de03032017-05-19 04:07:3411230 AlternativeServiceInfoVector alternative_service_info_vector =
11231 http_server_properties->GetAlternativeServiceInfos(test_server);
11232 ASSERT_EQ(1u, alternative_service_info_vector.size());
11233 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11234 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411235 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211236}
11237
bnce3dd56f2016-06-01 10:37:1111238// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111239TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111240 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111241 MockRead data_reads[] = {
11242 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311243 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111244 MockRead("\r\n"),
11245 MockRead("hello world"),
11246 MockRead(SYNCHRONOUS, OK),
11247 };
11248
11249 HttpRequestInfo request;
11250 request.method = "GET";
11251 request.url = GURL("http://www.example.org/");
11252 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011253 request.traffic_annotation =
11254 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111255
11256 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11257 session_deps_.socket_factory->AddSocketDataProvider(&data);
11258
11259 TestCompletionCallback callback;
11260
11261 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611262 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111263
11264 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011265 HttpServerProperties* http_server_properties =
11266 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411267 EXPECT_TRUE(
11268 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111269
tfarina42834112016-09-22 13:38:2011270 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11272 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111273
bnc691fda62016-08-12 00:43:1611274 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111275 ASSERT_TRUE(response);
11276 ASSERT_TRUE(response->headers);
11277 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11278 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211279 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111280
11281 std::string response_data;
bnc691fda62016-08-12 00:43:1611282 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111283 EXPECT_EQ("hello world", response_data);
11284
zhongyic4de03032017-05-19 04:07:3411285 EXPECT_TRUE(
11286 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111287}
11288
bnca86731e2017-04-17 12:31:2811289// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511290// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111291TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511292 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811293 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511294
bnc8bef8da22016-05-30 01:28:2511295 HttpRequestInfo request;
11296 request.method = "GET";
bncb26024382016-06-29 02:39:4511297 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511298 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011299 request.traffic_annotation =
11300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511301
11302 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11303 StaticSocketDataProvider first_data;
11304 first_data.set_connect_data(mock_connect);
11305 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511306 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611307 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511309
11310 MockRead data_reads[] = {
11311 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11312 MockRead(ASYNC, OK),
11313 };
11314 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11315 0);
11316 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11317
11318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11319
bnc525e175a2016-06-20 12:36:4011320 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511321 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111322 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11323 444);
bnc8bef8da22016-05-30 01:28:2511324 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111325 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511326 url::SchemeHostPort(request.url), alternative_service, expiration);
11327
bnc691fda62016-08-12 00:43:1611328 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511329 TestCompletionCallback callback;
11330
tfarina42834112016-09-22 13:38:2011331 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511332 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111333 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511334}
11335
bnce3dd56f2016-06-01 10:37:1111336// Regression test for https://crbug.com/615497:
11337// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111338TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111339 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111340 HttpRequestInfo request;
11341 request.method = "GET";
11342 request.url = GURL("http://www.example.org/");
11343 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011344 request.traffic_annotation =
11345 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111346
11347 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11348 StaticSocketDataProvider first_data;
11349 first_data.set_connect_data(mock_connect);
11350 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11351
11352 MockRead data_reads[] = {
11353 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11354 MockRead(ASYNC, OK),
11355 };
11356 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11357 0);
11358 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11359
11360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11361
bnc525e175a2016-06-20 12:36:4011362 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111363 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111364 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111365 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111366 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111367 url::SchemeHostPort(request.url), alternative_service, expiration);
11368
bnc691fda62016-08-12 00:43:1611369 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111370 TestCompletionCallback callback;
11371
tfarina42834112016-09-22 13:38:2011372 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111373 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111374 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111375}
11376
bncd16676a2016-07-20 16:23:0111377TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811378 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011380 HttpServerProperties* http_server_properties =
11381 session->http_server_properties();
bncb26024382016-06-29 02:39:4511382 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111383 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811384 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111385 http_server_properties->SetQuicAlternativeService(
11386 test_server, alternative_service, expiration,
11387 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411388 EXPECT_EQ(
11389 1u,
11390 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811391
11392 // Send a clear header.
11393 MockRead data_reads[] = {
11394 MockRead("HTTP/1.1 200 OK\r\n"),
11395 MockRead("Alt-Svc: clear\r\n"),
11396 MockRead("\r\n"),
11397 MockRead("hello world"),
11398 MockRead(SYNCHRONOUS, OK),
11399 };
11400 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
11401 session_deps_.socket_factory->AddSocketDataProvider(&data);
11402
bncb26024382016-06-29 02:39:4511403 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911404 ssl.ssl_info.cert =
11405 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11406 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11408
bnc4f575852015-10-14 18:35:0811409 HttpRequestInfo request;
11410 request.method = "GET";
bncb26024382016-06-29 02:39:4511411 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011412 request.traffic_annotation =
11413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811414
11415 TestCompletionCallback callback;
11416
bnc691fda62016-08-12 00:43:1611417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811418
tfarina42834112016-09-22 13:38:2011419 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111420 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811421
bnc691fda62016-08-12 00:43:1611422 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211423 ASSERT_TRUE(response);
11424 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811425 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11426 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211427 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811428
11429 std::string response_data;
bnc691fda62016-08-12 00:43:1611430 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811431 EXPECT_EQ("hello world", response_data);
11432
zhongyic4de03032017-05-19 04:07:3411433 EXPECT_TRUE(
11434 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811435}
11436
bncd16676a2016-07-20 16:23:0111437TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211438 MockRead data_reads[] = {
11439 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311440 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11441 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211442 MockRead("hello world"),
11443 MockRead(SYNCHRONOUS, OK),
11444 };
11445
11446 HttpRequestInfo request;
11447 request.method = "GET";
bncb26024382016-06-29 02:39:4511448 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011449 request.traffic_annotation =
11450 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211451
11452 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211453 session_deps_.socket_factory->AddSocketDataProvider(&data);
11454
bncb26024382016-06-29 02:39:4511455 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911456 ssl.ssl_info.cert =
11457 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11458 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11460
bncc958faa2015-07-31 18:14:5211461 TestCompletionCallback callback;
11462
danakj1fd259a02016-04-16 03:17:0911463 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211465
tfarina42834112016-09-22 13:38:2011466 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211468
bncb26024382016-06-29 02:39:4511469 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011470 HttpServerProperties* http_server_properties =
11471 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411472 EXPECT_TRUE(
11473 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211474
robpercival214763f2016-07-01 23:27:0111475 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211476
bnc691fda62016-08-12 00:43:1611477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211478 ASSERT_TRUE(response);
11479 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211480 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11481 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211482 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211483
11484 std::string response_data;
bnc691fda62016-08-12 00:43:1611485 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211486 EXPECT_EQ("hello world", response_data);
11487
zhongyic4de03032017-05-19 04:07:3411488 AlternativeServiceInfoVector alternative_service_info_vector =
11489 http_server_properties->GetAlternativeServiceInfos(test_server);
11490 ASSERT_EQ(2u, alternative_service_info_vector.size());
11491
11492 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11493 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411494 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411495 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11496 1234);
11497 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411498 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211499}
11500
bncd16676a2016-07-20 16:23:0111501TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611502 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211503 HostPortPair alternative("alternative.example.org", 443);
11504 std::string origin_url = "https://origin.example.org:443";
11505 std::string alternative_url = "https://alternative.example.org:443";
11506
11507 // Negotiate HTTP/1.1 with alternative.example.org.
11508 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611509 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211510 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11511
11512 // HTTP/1.1 data for request.
11513 MockWrite http_writes[] = {
11514 MockWrite("GET / HTTP/1.1\r\n"
11515 "Host: alternative.example.org\r\n"
11516 "Connection: keep-alive\r\n\r\n"),
11517 };
11518
11519 MockRead http_reads[] = {
11520 MockRead("HTTP/1.1 200 OK\r\n"
11521 "Content-Type: text/html; charset=iso-8859-1\r\n"
11522 "Content-Length: 40\r\n\r\n"
11523 "first HTTP/1.1 response from alternative"),
11524 };
11525 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11526 http_writes, arraysize(http_writes));
11527 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11528
11529 StaticSocketDataProvider data_refused;
11530 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11531 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11532
zhongyi3d4a55e72016-04-22 20:36:4611533 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011535 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211536 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111537 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211538 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111539 http_server_properties->SetQuicAlternativeService(
11540 server, alternative_service, expiration,
11541 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211542 // Mark the QUIC alternative service as broken.
11543 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11544
zhongyi48704c182015-12-07 07:52:0211545 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211547 request.method = "GET";
11548 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011549 request.traffic_annotation =
11550 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11551
zhongyi48704c182015-12-07 07:52:0211552 TestCompletionCallback callback;
11553 NetErrorDetails details;
11554 EXPECT_FALSE(details.quic_broken);
11555
tfarina42834112016-09-22 13:38:2011556 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611557 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211558 EXPECT_TRUE(details.quic_broken);
11559}
11560
bncd16676a2016-07-20 16:23:0111561TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611562 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211563 HostPortPair alternative1("alternative1.example.org", 443);
11564 HostPortPair alternative2("alternative2.example.org", 443);
11565 std::string origin_url = "https://origin.example.org:443";
11566 std::string alternative_url1 = "https://alternative1.example.org:443";
11567 std::string alternative_url2 = "https://alternative2.example.org:443";
11568
11569 // Negotiate HTTP/1.1 with alternative1.example.org.
11570 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611571 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211572 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11573
11574 // HTTP/1.1 data for request.
11575 MockWrite http_writes[] = {
11576 MockWrite("GET / HTTP/1.1\r\n"
11577 "Host: alternative1.example.org\r\n"
11578 "Connection: keep-alive\r\n\r\n"),
11579 };
11580
11581 MockRead http_reads[] = {
11582 MockRead("HTTP/1.1 200 OK\r\n"
11583 "Content-Type: text/html; charset=iso-8859-1\r\n"
11584 "Content-Length: 40\r\n\r\n"
11585 "first HTTP/1.1 response from alternative1"),
11586 };
11587 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11588 http_writes, arraysize(http_writes));
11589 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11590
11591 StaticSocketDataProvider data_refused;
11592 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11593 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11594
danakj1fd259a02016-04-16 03:17:0911595 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011596 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211597 session->http_server_properties();
11598
zhongyi3d4a55e72016-04-22 20:36:4611599 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211600 AlternativeServiceInfoVector alternative_service_info_vector;
11601 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11602
bnc3472afd2016-11-17 15:27:2111603 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111604 alternative_service_info_vector.push_back(
11605 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11606 alternative_service1, expiration,
11607 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111608 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111609 alternative_service_info_vector.push_back(
11610 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11611 alternative_service2, expiration,
11612 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211613
11614 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611615 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211616
11617 // Mark one of the QUIC alternative service as broken.
11618 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411619 EXPECT_EQ(2u,
11620 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211621
zhongyi48704c182015-12-07 07:52:0211622 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611623 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211624 request.method = "GET";
11625 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011626 request.traffic_annotation =
11627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11628
zhongyi48704c182015-12-07 07:52:0211629 TestCompletionCallback callback;
11630 NetErrorDetails details;
11631 EXPECT_FALSE(details.quic_broken);
11632
tfarina42834112016-09-22 13:38:2011633 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611634 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211635 EXPECT_FALSE(details.quic_broken);
11636}
11637
bncd16676a2016-07-20 16:23:0111638TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211639 HttpRequestInfo request;
11640 request.method = "GET";
bncb26024382016-06-29 02:39:4511641 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011642 request.traffic_annotation =
11643 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211644
[email protected]d973e99a2012-02-17 21:02:3611645 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211646 StaticSocketDataProvider first_data;
11647 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711648 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511649 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611650 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511651 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211652
11653 MockRead data_reads[] = {
11654 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11655 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611656 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211657 };
11658 StaticSocketDataProvider second_data(
11659 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711660 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211661
danakj1fd259a02016-04-16 03:17:0911662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211663
bnc525e175a2016-06-20 12:36:4011664 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311665 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611666 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111667 // Port must be < 1024, or the header will be ignored (since initial port was
11668 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111669 // Port is ignored by MockConnect anyway.
11670 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11671 666);
bnc7dc7e1b42015-07-28 14:43:1211672 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111673 http_server_properties->SetHttp2AlternativeService(
11674 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211675
bnc691fda62016-08-12 00:43:1611676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111677 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211678
tfarina42834112016-09-22 13:38:2011679 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11681 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211682
bnc691fda62016-08-12 00:43:1611683 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211684 ASSERT_TRUE(response);
11685 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211686 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11687
11688 std::string response_data;
bnc691fda62016-08-12 00:43:1611689 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211690 EXPECT_EQ("hello world", response_data);
11691
zhongyic4de03032017-05-19 04:07:3411692 const AlternativeServiceInfoVector alternative_service_info_vector =
11693 http_server_properties->GetAlternativeServiceInfos(server);
11694 ASSERT_EQ(1u, alternative_service_info_vector.size());
11695 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411696 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411697 EXPECT_TRUE(
11698 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211699}
11700
bnc55ff9da2015-08-19 18:42:3511701// Ensure that we are not allowed to redirect traffic via an alternate protocol
11702// to an unrestricted (port >= 1024) when the original traffic was on a
11703// restricted port (port < 1024). Ensure that we can redirect in all other
11704// cases.
bncd16676a2016-07-20 16:23:0111705TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111706 HttpRequestInfo restricted_port_request;
11707 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511708 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111709 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011710 restricted_port_request.traffic_annotation =
11711 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111712
[email protected]d973e99a2012-02-17 21:02:3611713 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111714 StaticSocketDataProvider first_data;
11715 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711716 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111717
11718 MockRead data_reads[] = {
11719 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11720 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611721 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111722 };
11723 StaticSocketDataProvider second_data(
11724 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711725 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511726 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611727 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111729
danakj1fd259a02016-04-16 03:17:0911730 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111731
bnc525e175a2016-06-20 12:36:4011732 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311733 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111734 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111735 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11736 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211737 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111738 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611739 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011740 expiration);
[email protected]3912662a32011-10-04 00:51:1111741
bnc691fda62016-08-12 00:43:1611742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111743 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111744
tfarina42834112016-09-22 13:38:2011745 int rv = trans.Start(&restricted_port_request, callback.callback(),
11746 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111748 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111749 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911750}
[email protected]3912662a32011-10-04 00:51:1111751
bnc55ff9da2015-08-19 18:42:3511752// Ensure that we are allowed to redirect traffic via an alternate protocol to
11753// an unrestricted (port >= 1024) when the original traffic was on a restricted
11754// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111755TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711756 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911757
11758 HttpRequestInfo restricted_port_request;
11759 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511760 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911761 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011762 restricted_port_request.traffic_annotation =
11763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911764
11765 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11766 StaticSocketDataProvider first_data;
11767 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711768 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911769
11770 MockRead data_reads[] = {
11771 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11772 MockRead("hello world"),
11773 MockRead(ASYNC, OK),
11774 };
11775 StaticSocketDataProvider second_data(
11776 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711777 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511778 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611779 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511780 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911781
danakj1fd259a02016-04-16 03:17:0911782 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911783
bnc525e175a2016-06-20 12:36:4011784 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911785 session->http_server_properties();
11786 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111787 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11788 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211789 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111790 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611791 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011792 expiration);
[email protected]c54c6962013-02-01 04:53:1911793
bnc691fda62016-08-12 00:43:1611794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911795 TestCompletionCallback callback;
11796
tfarina42834112016-09-22 13:38:2011797 EXPECT_EQ(ERR_IO_PENDING,
11798 trans.Start(&restricted_port_request, callback.callback(),
11799 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911800 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111801 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111802}
11803
bnc55ff9da2015-08-19 18:42:3511804// Ensure that we are not allowed to redirect traffic via an alternate protocol
11805// to an unrestricted (port >= 1024) when the original traffic was on a
11806// restricted port (port < 1024). Ensure that we can redirect in all other
11807// cases.
bncd16676a2016-07-20 16:23:0111808TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111809 HttpRequestInfo restricted_port_request;
11810 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511811 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111812 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011813 restricted_port_request.traffic_annotation =
11814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111815
[email protected]d973e99a2012-02-17 21:02:3611816 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111817 StaticSocketDataProvider first_data;
11818 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711819 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111820
11821 MockRead data_reads[] = {
11822 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11823 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611824 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111825 };
11826 StaticSocketDataProvider second_data(
11827 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711828 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111829
bncb26024382016-06-29 02:39:4511830 SSLSocketDataProvider ssl(ASYNC, OK);
11831 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11832
danakj1fd259a02016-04-16 03:17:0911833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111834
bnc525e175a2016-06-20 12:36:4011835 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311836 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111837 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111838 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11839 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211840 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111841 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611842 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011843 expiration);
[email protected]3912662a32011-10-04 00:51:1111844
bnc691fda62016-08-12 00:43:1611845 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111846 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111847
tfarina42834112016-09-22 13:38:2011848 int rv = trans.Start(&restricted_port_request, callback.callback(),
11849 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111850 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111851 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111852 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111853}
11854
bnc55ff9da2015-08-19 18:42:3511855// Ensure that we are not allowed to redirect traffic via an alternate protocol
11856// to an unrestricted (port >= 1024) when the original traffic was on a
11857// restricted port (port < 1024). Ensure that we can redirect in all other
11858// cases.
bncd16676a2016-07-20 16:23:0111859TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111860 HttpRequestInfo unrestricted_port_request;
11861 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511862 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111863 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011864 unrestricted_port_request.traffic_annotation =
11865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111866
[email protected]d973e99a2012-02-17 21:02:3611867 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111868 StaticSocketDataProvider first_data;
11869 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711870 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111871
11872 MockRead data_reads[] = {
11873 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11874 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611875 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111876 };
11877 StaticSocketDataProvider second_data(
11878 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711879 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511880 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611881 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111883
danakj1fd259a02016-04-16 03:17:0911884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111885
bnc525e175a2016-06-20 12:36:4011886 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311887 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111888 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111889 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11890 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211891 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111892 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611893 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011894 expiration);
[email protected]3912662a32011-10-04 00:51:1111895
bnc691fda62016-08-12 00:43:1611896 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111897 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111898
bnc691fda62016-08-12 00:43:1611899 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011900 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111902 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111903 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111904}
11905
bnc55ff9da2015-08-19 18:42:3511906// Ensure that we are not allowed to redirect traffic via an alternate protocol
11907// to an unrestricted (port >= 1024) when the original traffic was on a
11908// restricted port (port < 1024). Ensure that we can redirect in all other
11909// cases.
bncd16676a2016-07-20 16:23:0111910TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111911 HttpRequestInfo unrestricted_port_request;
11912 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511913 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111914 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011915 unrestricted_port_request.traffic_annotation =
11916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111917
[email protected]d973e99a2012-02-17 21:02:3611918 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111919 StaticSocketDataProvider first_data;
11920 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711921 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111922
11923 MockRead data_reads[] = {
11924 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11925 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611926 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111927 };
11928 StaticSocketDataProvider second_data(
11929 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711930 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111931
bncb26024382016-06-29 02:39:4511932 SSLSocketDataProvider ssl(ASYNC, OK);
11933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11934
danakj1fd259a02016-04-16 03:17:0911935 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111936
bnc525e175a2016-06-20 12:36:4011937 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311938 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211939 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111940 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11941 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211942 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111943 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611944 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011945 expiration);
[email protected]3912662a32011-10-04 00:51:1111946
bnc691fda62016-08-12 00:43:1611947 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111948 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111949
bnc691fda62016-08-12 00:43:1611950 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011951 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111952 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111953 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111954 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111955}
11956
bnc55ff9da2015-08-19 18:42:3511957// Ensure that we are not allowed to redirect traffic via an alternate protocol
11958// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11959// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111960TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211961 HttpRequestInfo request;
11962 request.method = "GET";
bncce36dca22015-04-21 22:11:2311963 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011964 request.traffic_annotation =
11965 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211966
11967 // The alternate protocol request will error out before we attempt to connect,
11968 // so only the standard HTTP request will try to connect.
11969 MockRead data_reads[] = {
11970 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11971 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611972 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211973 };
11974 StaticSocketDataProvider data(
11975 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711976 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211977
danakj1fd259a02016-04-16 03:17:0911978 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211979
bnc525e175a2016-06-20 12:36:4011980 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211981 session->http_server_properties();
11982 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111983 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11984 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211985 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111986 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611987 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211988
bnc691fda62016-08-12 00:43:1611989 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211990 TestCompletionCallback callback;
11991
tfarina42834112016-09-22 13:38:2011992 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211994 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111995 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211996
bnc691fda62016-08-12 00:43:1611997 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211998 ASSERT_TRUE(response);
11999 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212000 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12001
12002 std::string response_data;
bnc691fda62016-08-12 00:43:1612003 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212004 EXPECT_EQ("hello world", response_data);
12005}
12006
bncd16676a2016-07-20 16:23:0112007TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412008 HttpRequestInfo request;
12009 request.method = "GET";
bncb26024382016-06-29 02:39:4512010 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012011 request.traffic_annotation =
12012 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412013
12014 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212015 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312016 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212017 MockRead("\r\n"),
12018 MockRead("hello world"),
12019 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12020 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412021
12022 StaticSocketDataProvider first_transaction(
12023 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712024 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512025 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612026 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512027 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412028
bnc032658ba2016-09-26 18:17:1512029 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412030
bncdf80d44fd2016-07-15 20:27:4112031 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512032 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112033 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412034
bnc42331402016-07-25 13:36:1512035 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112036 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412037 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112038 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412039 };
12040
rch8e6c6c42015-05-01 14:05:1312041 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12042 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712043 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412044
[email protected]d973e99a2012-02-17 21:02:3612045 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512046 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12047 NULL, 0, NULL, 0);
12048 hanging_non_alternate_protocol_socket.set_connect_data(
12049 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712050 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512051 &hanging_non_alternate_protocol_socket);
12052
[email protected]49639fa2011-12-20 23:22:4112053 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412054
danakj1fd259a02016-04-16 03:17:0912055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812056 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912057 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412058
tfarina42834112016-09-22 13:38:2012059 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12061 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412062
12063 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212064 ASSERT_TRUE(response);
12065 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412066 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12067
12068 std::string response_data;
robpercival214763f2016-07-01 23:27:0112069 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412070 EXPECT_EQ("hello world", response_data);
12071
bnc87dcefc2017-05-25 12:47:5812072 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912073 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412074
tfarina42834112016-09-22 13:38:2012075 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12077 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412078
12079 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212080 ASSERT_TRUE(response);
12081 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212082 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312083 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212084 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412085
robpercival214763f2016-07-01 23:27:0112086 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412087 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412088}
12089
bncd16676a2016-07-20 16:23:0112090TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512091 HttpRequestInfo request;
12092 request.method = "GET";
bncb26024382016-06-29 02:39:4512093 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012094 request.traffic_annotation =
12095 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512096
bncb26024382016-06-29 02:39:4512097 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512098 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212099 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312100 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212101 MockRead("\r\n"),
12102 MockRead("hello world"),
12103 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12104 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512105 };
12106
bncb26024382016-06-29 02:39:4512107 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
12108 0);
12109 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512110
bncb26024382016-06-29 02:39:4512111 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912112 ssl_http11.ssl_info.cert =
12113 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12114 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12116
12117 // Second transaction starts an alternative and a non-alternative Job.
12118 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612119 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1812120 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
12121 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812122 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12123
12124 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
12125 hanging_socket2.set_connect_data(never_finishing_connect);
12126 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512127
bncb26024382016-06-29 02:39:4512128 // Third transaction starts an alternative and a non-alternative job.
12129 // The non-alternative job hangs, but the alternative one succeeds.
12130 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4112131 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512132 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112133 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512134 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512135 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112136 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512137 };
bnc42331402016-07-25 13:36:1512138 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112139 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512140 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112141 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512142 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112143 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12144 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312145 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512146 };
12147
rch8e6c6c42015-05-01 14:05:1312148 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12149 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712150 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512151
bnc032658ba2016-09-26 18:17:1512152 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512153
mmenkecc2298e2015-12-07 18:20:1812154 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
12155 hanging_socket3.set_connect_data(never_finishing_connect);
12156 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512157
danakj1fd259a02016-04-16 03:17:0912158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112159 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012160 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512161
tfarina42834112016-09-22 13:38:2012162 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12164 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512165
12166 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212167 ASSERT_TRUE(response);
12168 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512169 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12170
12171 std::string response_data;
robpercival214763f2016-07-01 23:27:0112172 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512173 EXPECT_EQ("hello world", response_data);
12174
[email protected]49639fa2011-12-20 23:22:4112175 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012176 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012177 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512179
[email protected]49639fa2011-12-20 23:22:4112180 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012181 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012182 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512184
robpercival214763f2016-07-01 23:27:0112185 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12186 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512187
12188 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212189 ASSERT_TRUE(response);
12190 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212191 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512192 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212193 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112194 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512195 EXPECT_EQ("hello!", response_data);
12196
12197 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212198 ASSERT_TRUE(response);
12199 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212200 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512201 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212202 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112203 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512204 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512205}
12206
bncd16676a2016-07-20 16:23:0112207TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512208 HttpRequestInfo request;
12209 request.method = "GET";
bncb26024382016-06-29 02:39:4512210 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012211 request.traffic_annotation =
12212 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512213
12214 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212215 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312216 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212217 MockRead("\r\n"),
12218 MockRead("hello world"),
12219 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12220 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512221 };
12222
12223 StaticSocketDataProvider first_transaction(
12224 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712225 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512226
[email protected]8ddf8322012-02-23 18:08:0612227 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912228 ssl.ssl_info.cert =
12229 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12230 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712231 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512232
[email protected]d973e99a2012-02-17 21:02:3612233 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512234 StaticSocketDataProvider hanging_alternate_protocol_socket(
12235 NULL, 0, NULL, 0);
12236 hanging_alternate_protocol_socket.set_connect_data(
12237 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712238 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512239 &hanging_alternate_protocol_socket);
12240
bncb26024382016-06-29 02:39:4512241 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1812242 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
12243 NULL, 0);
12244 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512246
[email protected]49639fa2011-12-20 23:22:4112247 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512248
danakj1fd259a02016-04-16 03:17:0912249 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812250 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912251 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512252
tfarina42834112016-09-22 13:38:2012253 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12255 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512256
12257 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212258 ASSERT_TRUE(response);
12259 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512260 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12261
12262 std::string response_data;
robpercival214763f2016-07-01 23:27:0112263 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512264 EXPECT_EQ("hello world", response_data);
12265
bnc87dcefc2017-05-25 12:47:5812266 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912267 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512268
tfarina42834112016-09-22 13:38:2012269 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12271 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512272
12273 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212274 ASSERT_TRUE(response);
12275 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512276 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12277 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212278 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512279
robpercival214763f2016-07-01 23:27:0112280 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512281 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512282}
12283
[email protected]631f1322010-04-30 17:59:1112284class CapturingProxyResolver : public ProxyResolver {
12285 public:
Chris Watkins7a41d3552017-12-01 02:13:2712286 CapturingProxyResolver() = default;
12287 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112288
dchengb03027d2014-10-21 12:00:2012289 int GetProxyForURL(const GURL& url,
12290 ProxyInfo* results,
12291 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512292 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012293 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012294 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12295 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212296 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112297 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212298 return OK;
[email protected]631f1322010-04-30 17:59:1112299 }
12300
[email protected]24476402010-07-20 20:55:1712301 const std::vector<GURL>& resolved() const { return resolved_; }
12302
12303 private:
[email protected]631f1322010-04-30 17:59:1112304 std::vector<GURL> resolved_;
12305
12306 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12307};
12308
sammce64b2362015-04-29 03:50:2312309class CapturingProxyResolverFactory : public ProxyResolverFactory {
12310 public:
12311 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12312 : ProxyResolverFactory(false), resolver_(resolver) {}
12313
Lily Houghton99597862018-03-07 16:40:4212314 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12315 std::unique_ptr<ProxyResolver>* resolver,
12316 const net::CompletionCallback& callback,
12317 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912318 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312319 return OK;
12320 }
12321
12322 private:
12323 ProxyResolver* resolver_;
12324};
12325
bnc2e884782016-08-11 19:45:1912326// Test that proxy is resolved using the origin url,
12327// regardless of the alternative server.
12328TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12329 // Configure proxy to bypass www.example.org, which is the origin URL.
12330 ProxyConfig proxy_config;
12331 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12332 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912333 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12334 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912335
12336 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912337 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912338 &capturing_proxy_resolver);
12339
12340 TestNetLog net_log;
12341
Bence Béky53a5aef2018-03-29 21:54:1212342 session_deps_.proxy_resolution_service =
12343 std::make_unique<ProxyResolutionService>(
12344 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12345 &net_log);
bnc2e884782016-08-11 19:45:1912346
12347 session_deps_.net_log = &net_log;
12348
12349 // Configure alternative service with a hostname that is not bypassed by the
12350 // proxy.
12351 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12352 HttpServerProperties* http_server_properties =
12353 session->http_server_properties();
12354 url::SchemeHostPort server("https", "www.example.org", 443);
12355 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112356 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912357 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112358 http_server_properties->SetHttp2AlternativeService(
12359 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912360
12361 // Non-alternative job should hang.
12362 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
12363 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
12364 nullptr, 0);
12365 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12366 session_deps_.socket_factory->AddSocketDataProvider(
12367 &hanging_alternate_protocol_socket);
12368
bnc032658ba2016-09-26 18:17:1512369 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912370
12371 HttpRequestInfo request;
12372 request.method = "GET";
12373 request.url = GURL("https://www.example.org/");
12374 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012375 request.traffic_annotation =
12376 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912377
12378 SpdySerializedFrame req(
12379 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12380
12381 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12382
12383 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12384 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12385 MockRead spdy_reads[] = {
12386 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12387 };
12388
12389 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12390 arraysize(spdy_writes));
12391 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12392
12393 TestCompletionCallback callback;
12394
12395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12396
tfarina42834112016-09-22 13:38:2012397 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912398 EXPECT_THAT(callback.GetResult(rv), IsOk());
12399
12400 const HttpResponseInfo* response = trans.GetResponseInfo();
12401 ASSERT_TRUE(response);
12402 ASSERT_TRUE(response->headers);
12403 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12404 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212405 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912406
12407 std::string response_data;
12408 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12409 EXPECT_EQ("hello!", response_data);
12410
12411 // Origin host bypasses proxy, no resolution should have happened.
12412 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12413}
12414
bncd16676a2016-07-20 16:23:0112415TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112416 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212417 proxy_config.set_auto_detect(true);
12418 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112419
sammc5dd160c2015-04-02 02:43:1312420 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912421 session_deps_.proxy_resolution_service =
12422 std::make_unique<ProxyResolutionService>(
12423 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12424 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12425 std::make_unique<CapturingProxyResolverFactory>(
12426 &capturing_proxy_resolver),
12427 nullptr);
vishal.b62985ca92015-04-17 08:45:5112428 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712429 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112430
12431 HttpRequestInfo request;
12432 request.method = "GET";
bncb26024382016-06-29 02:39:4512433 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012434 request.traffic_annotation =
12435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112436
12437 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212438 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312439 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212440 MockRead("\r\n"),
12441 MockRead("hello world"),
12442 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12443 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112444 };
12445
12446 StaticSocketDataProvider first_transaction(
12447 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712448 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512449 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612450 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512451 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112452
bnc032658ba2016-09-26 18:17:1512453 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112454
bncdf80d44fd2016-07-15 20:27:4112455 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512456 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112457 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312458 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512459 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12460 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312461 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112462 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112463 };
12464
[email protected]d911f1b2010-05-05 22:39:4212465 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12466
bnc42331402016-07-25 13:36:1512467 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112468 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112469 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112470 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12471 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112472 };
12473
rch8e6c6c42015-05-01 14:05:1312474 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12475 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712476 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112477
[email protected]d973e99a2012-02-17 21:02:3612478 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512479 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12480 NULL, 0, NULL, 0);
12481 hanging_non_alternate_protocol_socket.set_connect_data(
12482 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712483 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512484 &hanging_non_alternate_protocol_socket);
12485
[email protected]49639fa2011-12-20 23:22:4112486 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112487
danakj1fd259a02016-04-16 03:17:0912488 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812489 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912490 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112491
tfarina42834112016-09-22 13:38:2012492 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12494 EXPECT_THAT(callback.WaitForResult(), IsOk());
12495
12496 const HttpResponseInfo* response = trans->GetResponseInfo();
12497 ASSERT_TRUE(response);
12498 ASSERT_TRUE(response->headers);
12499 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12500 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212501 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112502
12503 std::string response_data;
12504 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12505 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112506
bnc87dcefc2017-05-25 12:47:5812507 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912508 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112509
tfarina42834112016-09-22 13:38:2012510 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112511 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12512 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112513
mmenkea2dcd3bf2016-08-16 21:49:4112514 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212515 ASSERT_TRUE(response);
12516 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212517 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312518 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212519 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112520
robpercival214763f2016-07-01 23:27:0112521 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112522 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512523 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12524 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312525 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312526 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312527 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112528
[email protected]029c83b62013-01-24 05:28:2012529 LoadTimingInfo load_timing_info;
12530 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12531 TestLoadTimingNotReusedWithPac(load_timing_info,
12532 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112533}
[email protected]631f1322010-04-30 17:59:1112534
bncd16676a2016-07-20 16:23:0112535TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812536 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412537 HttpRequestInfo request;
12538 request.method = "GET";
bncb26024382016-06-29 02:39:4512539 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012540 request.traffic_annotation =
12541 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412542
12543 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212544 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312545 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212546 MockRead("\r\n"),
12547 MockRead("hello world"),
12548 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412549 };
12550
12551 StaticSocketDataProvider first_transaction(
12552 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712553 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512554 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612555 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412557
bnc032658ba2016-09-26 18:17:1512558 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412559
bncdf80d44fd2016-07-15 20:27:4112560 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512561 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112562 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412563
bnc42331402016-07-25 13:36:1512564 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112565 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412566 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112567 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412568 };
12569
rch8e6c6c42015-05-01 14:05:1312570 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12571 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712572 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412573
[email protected]83039bb2011-12-09 18:43:5512574 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412575
danakj1fd259a02016-04-16 03:17:0912576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412577
bnc87dcefc2017-05-25 12:47:5812578 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912579 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412580
tfarina42834112016-09-22 13:38:2012581 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12583 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412584
12585 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212586 ASSERT_TRUE(response);
12587 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412588 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12589
12590 std::string response_data;
robpercival214763f2016-07-01 23:27:0112591 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412592 EXPECT_EQ("hello world", response_data);
12593
12594 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512595 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012596 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412597 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712598 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212599 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812600
bnc87dcefc2017-05-25 12:47:5812601 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912602 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412603
tfarina42834112016-09-22 13:38:2012604 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12606 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412607
12608 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212609 ASSERT_TRUE(response);
12610 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212611 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312612 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212613 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412614
robpercival214763f2016-07-01 23:27:0112615 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412616 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212617}
12618
[email protected]044de0642010-06-17 10:42:1512619// GenerateAuthToken is a mighty big test.
12620// It tests all permutation of GenerateAuthToken behavior:
12621// - Synchronous and Asynchronous completion.
12622// - OK or error on completion.
12623// - Direct connection, non-authenticating proxy, and authenticating proxy.
12624// - HTTP or HTTPS backend (to include proxy tunneling).
12625// - Non-authenticating and authenticating backend.
12626//
[email protected]fe3b7dc2012-02-03 19:52:0912627// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512628// problems generating an auth token for an authenticating proxy, we don't
12629// need to test all permutations of the backend server).
12630//
12631// The test proceeds by going over each of the configuration cases, and
12632// potentially running up to three rounds in each of the tests. The TestConfig
12633// specifies both the configuration for the test as well as the expectations
12634// for the results.
bncd16676a2016-07-20 16:23:0112635TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012636 static const char kServer[] = "http://www.example.com";
12637 static const char kSecureServer[] = "https://www.example.com";
12638 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512639
12640 enum AuthTiming {
12641 AUTH_NONE,
12642 AUTH_SYNC,
12643 AUTH_ASYNC,
12644 };
12645
12646 const MockWrite kGet(
12647 "GET / HTTP/1.1\r\n"
12648 "Host: www.example.com\r\n"
12649 "Connection: keep-alive\r\n\r\n");
12650 const MockWrite kGetProxy(
12651 "GET http://www.example.com/ HTTP/1.1\r\n"
12652 "Host: www.example.com\r\n"
12653 "Proxy-Connection: keep-alive\r\n\r\n");
12654 const MockWrite kGetAuth(
12655 "GET / HTTP/1.1\r\n"
12656 "Host: www.example.com\r\n"
12657 "Connection: keep-alive\r\n"
12658 "Authorization: auth_token\r\n\r\n");
12659 const MockWrite kGetProxyAuth(
12660 "GET http://www.example.com/ HTTP/1.1\r\n"
12661 "Host: www.example.com\r\n"
12662 "Proxy-Connection: keep-alive\r\n"
12663 "Proxy-Authorization: auth_token\r\n\r\n");
12664 const MockWrite kGetAuthThroughProxy(
12665 "GET http://www.example.com/ HTTP/1.1\r\n"
12666 "Host: www.example.com\r\n"
12667 "Proxy-Connection: keep-alive\r\n"
12668 "Authorization: auth_token\r\n\r\n");
12669 const MockWrite kGetAuthWithProxyAuth(
12670 "GET http://www.example.com/ HTTP/1.1\r\n"
12671 "Host: www.example.com\r\n"
12672 "Proxy-Connection: keep-alive\r\n"
12673 "Proxy-Authorization: auth_token\r\n"
12674 "Authorization: auth_token\r\n\r\n");
12675 const MockWrite kConnect(
12676 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712677 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512678 "Proxy-Connection: keep-alive\r\n\r\n");
12679 const MockWrite kConnectProxyAuth(
12680 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712681 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512682 "Proxy-Connection: keep-alive\r\n"
12683 "Proxy-Authorization: auth_token\r\n\r\n");
12684
12685 const MockRead kSuccess(
12686 "HTTP/1.1 200 OK\r\n"
12687 "Content-Type: text/html; charset=iso-8859-1\r\n"
12688 "Content-Length: 3\r\n\r\n"
12689 "Yes");
12690 const MockRead kFailure(
12691 "Should not be called.");
12692 const MockRead kServerChallenge(
12693 "HTTP/1.1 401 Unauthorized\r\n"
12694 "WWW-Authenticate: Mock realm=server\r\n"
12695 "Content-Type: text/html; charset=iso-8859-1\r\n"
12696 "Content-Length: 14\r\n\r\n"
12697 "Unauthorized\r\n");
12698 const MockRead kProxyChallenge(
12699 "HTTP/1.1 407 Unauthorized\r\n"
12700 "Proxy-Authenticate: Mock realm=proxy\r\n"
12701 "Proxy-Connection: close\r\n"
12702 "Content-Type: text/html; charset=iso-8859-1\r\n"
12703 "Content-Length: 14\r\n\r\n"
12704 "Unauthorized\r\n");
12705 const MockRead kProxyConnected(
12706 "HTTP/1.1 200 Connection Established\r\n\r\n");
12707
12708 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12709 // no constructors, but the C++ compiler on Windows warns about
12710 // unspecified data in compound literals. So, moved to using constructors,
12711 // and TestRound's created with the default constructor should not be used.
12712 struct TestRound {
12713 TestRound()
12714 : expected_rv(ERR_UNEXPECTED),
12715 extra_write(NULL),
12716 extra_read(NULL) {
12717 }
12718 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12719 int expected_rv_arg)
12720 : write(write_arg),
12721 read(read_arg),
12722 expected_rv(expected_rv_arg),
12723 extra_write(NULL),
12724 extra_read(NULL) {
12725 }
12726 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12727 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112728 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512729 : write(write_arg),
12730 read(read_arg),
12731 expected_rv(expected_rv_arg),
12732 extra_write(extra_write_arg),
12733 extra_read(extra_read_arg) {
12734 }
12735 MockWrite write;
12736 MockRead read;
12737 int expected_rv;
12738 const MockWrite* extra_write;
12739 const MockRead* extra_read;
12740 };
12741
12742 static const int kNoSSL = 500;
12743
12744 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112745 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112746 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512747 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112748 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112749 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512750 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112751 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512752 int num_auth_rounds;
12753 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612754 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512755 } test_configs[] = {
asankac93076192016-10-03 15:46:0212756 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112757 {__LINE__,
12758 nullptr,
asankac93076192016-10-03 15:46:0212759 AUTH_NONE,
12760 OK,
12761 kServer,
12762 AUTH_NONE,
12763 OK,
12764 1,
12765 kNoSSL,
12766 {TestRound(kGet, kSuccess, OK)}},
12767 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112768 {__LINE__,
12769 nullptr,
asankac93076192016-10-03 15:46:0212770 AUTH_NONE,
12771 OK,
12772 kServer,
12773 AUTH_SYNC,
12774 OK,
12775 2,
12776 kNoSSL,
12777 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512778 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112779 {__LINE__,
12780 nullptr,
asankac93076192016-10-03 15:46:0212781 AUTH_NONE,
12782 OK,
12783 kServer,
12784 AUTH_SYNC,
12785 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612786 3,
12787 kNoSSL,
12788 {TestRound(kGet, kServerChallenge, OK),
12789 TestRound(kGet, kServerChallenge, OK),
12790 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112791 {__LINE__,
12792 nullptr,
asankae2257db2016-10-11 22:03:1612793 AUTH_NONE,
12794 OK,
12795 kServer,
12796 AUTH_SYNC,
12797 ERR_UNSUPPORTED_AUTH_SCHEME,
12798 2,
12799 kNoSSL,
12800 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112801 {__LINE__,
12802 nullptr,
asankae2257db2016-10-11 22:03:1612803 AUTH_NONE,
12804 OK,
12805 kServer,
12806 AUTH_SYNC,
12807 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12808 2,
12809 kNoSSL,
12810 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112811 {__LINE__,
12812 kProxy,
asankae2257db2016-10-11 22:03:1612813 AUTH_SYNC,
12814 ERR_FAILED,
12815 kServer,
12816 AUTH_NONE,
12817 OK,
12818 2,
12819 kNoSSL,
12820 {TestRound(kGetProxy, kProxyChallenge, OK),
12821 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112822 {__LINE__,
12823 kProxy,
asankae2257db2016-10-11 22:03:1612824 AUTH_ASYNC,
12825 ERR_FAILED,
12826 kServer,
12827 AUTH_NONE,
12828 OK,
12829 2,
12830 kNoSSL,
12831 {TestRound(kGetProxy, kProxyChallenge, OK),
12832 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112833 {__LINE__,
12834 nullptr,
asankae2257db2016-10-11 22:03:1612835 AUTH_NONE,
12836 OK,
12837 kServer,
12838 AUTH_SYNC,
12839 ERR_FAILED,
asankac93076192016-10-03 15:46:0212840 2,
12841 kNoSSL,
12842 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612843 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112844 {__LINE__,
12845 nullptr,
asankae2257db2016-10-11 22:03:1612846 AUTH_NONE,
12847 OK,
12848 kServer,
12849 AUTH_ASYNC,
12850 ERR_FAILED,
12851 2,
12852 kNoSSL,
12853 {TestRound(kGet, kServerChallenge, OK),
12854 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112855 {__LINE__,
12856 nullptr,
asankac93076192016-10-03 15:46:0212857 AUTH_NONE,
12858 OK,
12859 kServer,
12860 AUTH_ASYNC,
12861 OK,
12862 2,
12863 kNoSSL,
12864 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512865 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112866 {__LINE__,
12867 nullptr,
asankac93076192016-10-03 15:46:0212868 AUTH_NONE,
12869 OK,
12870 kServer,
12871 AUTH_ASYNC,
12872 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612873 3,
asankac93076192016-10-03 15:46:0212874 kNoSSL,
12875 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612876 // The second round uses a HttpAuthHandlerMock that always succeeds.
12877 TestRound(kGet, kServerChallenge, OK),
12878 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212879 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112880 {__LINE__,
12881 kProxy,
asankac93076192016-10-03 15:46:0212882 AUTH_NONE,
12883 OK,
12884 kServer,
12885 AUTH_NONE,
12886 OK,
12887 1,
12888 kNoSSL,
12889 {TestRound(kGetProxy, kSuccess, OK)}},
12890 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112891 {__LINE__,
12892 kProxy,
asankac93076192016-10-03 15:46:0212893 AUTH_NONE,
12894 OK,
12895 kServer,
12896 AUTH_SYNC,
12897 OK,
12898 2,
12899 kNoSSL,
12900 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512901 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112902 {__LINE__,
12903 kProxy,
asankac93076192016-10-03 15:46:0212904 AUTH_NONE,
12905 OK,
12906 kServer,
12907 AUTH_SYNC,
12908 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612909 3,
asankac93076192016-10-03 15:46:0212910 kNoSSL,
12911 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612912 TestRound(kGetProxy, kServerChallenge, OK),
12913 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112914 {__LINE__,
12915 kProxy,
asankac93076192016-10-03 15:46:0212916 AUTH_NONE,
12917 OK,
12918 kServer,
12919 AUTH_ASYNC,
12920 OK,
12921 2,
12922 kNoSSL,
12923 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512924 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112925 {__LINE__,
12926 kProxy,
asankac93076192016-10-03 15:46:0212927 AUTH_NONE,
12928 OK,
12929 kServer,
12930 AUTH_ASYNC,
12931 ERR_INVALID_AUTH_CREDENTIALS,
12932 2,
12933 kNoSSL,
12934 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612935 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212936 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112937 {__LINE__,
12938 kProxy,
asankac93076192016-10-03 15:46:0212939 AUTH_SYNC,
12940 OK,
12941 kServer,
12942 AUTH_NONE,
12943 OK,
12944 2,
12945 kNoSSL,
12946 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512947 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112948 {__LINE__,
12949 kProxy,
asankac93076192016-10-03 15:46:0212950 AUTH_SYNC,
12951 ERR_INVALID_AUTH_CREDENTIALS,
12952 kServer,
12953 AUTH_NONE,
12954 OK,
12955 2,
12956 kNoSSL,
12957 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612958 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112959 {__LINE__,
12960 kProxy,
asankac93076192016-10-03 15:46:0212961 AUTH_ASYNC,
12962 OK,
12963 kServer,
12964 AUTH_NONE,
12965 OK,
12966 2,
12967 kNoSSL,
12968 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512969 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112970 {__LINE__,
12971 kProxy,
asankac93076192016-10-03 15:46:0212972 AUTH_ASYNC,
12973 ERR_INVALID_AUTH_CREDENTIALS,
12974 kServer,
12975 AUTH_NONE,
12976 OK,
12977 2,
12978 kNoSSL,
12979 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612980 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112981 {__LINE__,
12982 kProxy,
12983 AUTH_ASYNC,
12984 ERR_INVALID_AUTH_CREDENTIALS,
12985 kServer,
12986 AUTH_NONE,
12987 OK,
12988 3,
12989 kNoSSL,
12990 {TestRound(kGetProxy, kProxyChallenge, OK),
12991 TestRound(kGetProxy, kProxyChallenge, OK),
12992 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212993 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112994 {__LINE__,
12995 kProxy,
asankac93076192016-10-03 15:46:0212996 AUTH_SYNC,
12997 OK,
12998 kServer,
12999 AUTH_SYNC,
13000 OK,
13001 3,
13002 kNoSSL,
13003 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513004 TestRound(kGetProxyAuth, kServerChallenge, OK),
13005 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113006 {__LINE__,
13007 kProxy,
asankac93076192016-10-03 15:46:0213008 AUTH_SYNC,
13009 OK,
13010 kServer,
13011 AUTH_SYNC,
13012 ERR_INVALID_AUTH_CREDENTIALS,
13013 3,
13014 kNoSSL,
13015 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513016 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613017 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113018 {__LINE__,
13019 kProxy,
asankac93076192016-10-03 15:46:0213020 AUTH_ASYNC,
13021 OK,
13022 kServer,
13023 AUTH_SYNC,
13024 OK,
13025 3,
13026 kNoSSL,
13027 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513028 TestRound(kGetProxyAuth, kServerChallenge, OK),
13029 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113030 {__LINE__,
13031 kProxy,
asankac93076192016-10-03 15:46:0213032 AUTH_ASYNC,
13033 OK,
13034 kServer,
13035 AUTH_SYNC,
13036 ERR_INVALID_AUTH_CREDENTIALS,
13037 3,
13038 kNoSSL,
13039 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513040 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613041 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113042 {__LINE__,
13043 kProxy,
asankac93076192016-10-03 15:46:0213044 AUTH_SYNC,
13045 OK,
13046 kServer,
13047 AUTH_ASYNC,
13048 OK,
13049 3,
13050 kNoSSL,
13051 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513052 TestRound(kGetProxyAuth, kServerChallenge, OK),
13053 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113054 {__LINE__,
13055 kProxy,
13056 AUTH_SYNC,
13057 ERR_INVALID_AUTH_CREDENTIALS,
13058 kServer,
13059 AUTH_ASYNC,
13060 OK,
13061 4,
13062 kNoSSL,
13063 {TestRound(kGetProxy, kProxyChallenge, OK),
13064 TestRound(kGetProxy, kProxyChallenge, OK),
13065 TestRound(kGetProxyAuth, kServerChallenge, OK),
13066 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13067 {__LINE__,
13068 kProxy,
asankac93076192016-10-03 15:46:0213069 AUTH_SYNC,
13070 OK,
13071 kServer,
13072 AUTH_ASYNC,
13073 ERR_INVALID_AUTH_CREDENTIALS,
13074 3,
13075 kNoSSL,
13076 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513077 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613078 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113079 {__LINE__,
13080 kProxy,
asankac93076192016-10-03 15:46:0213081 AUTH_ASYNC,
13082 OK,
13083 kServer,
13084 AUTH_ASYNC,
13085 OK,
13086 3,
13087 kNoSSL,
13088 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513089 TestRound(kGetProxyAuth, kServerChallenge, OK),
13090 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113091 {__LINE__,
13092 kProxy,
asankac93076192016-10-03 15:46:0213093 AUTH_ASYNC,
13094 OK,
13095 kServer,
13096 AUTH_ASYNC,
13097 ERR_INVALID_AUTH_CREDENTIALS,
13098 3,
13099 kNoSSL,
13100 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513101 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613102 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113103 {__LINE__,
13104 kProxy,
13105 AUTH_ASYNC,
13106 ERR_INVALID_AUTH_CREDENTIALS,
13107 kServer,
13108 AUTH_ASYNC,
13109 ERR_INVALID_AUTH_CREDENTIALS,
13110 4,
13111 kNoSSL,
13112 {TestRound(kGetProxy, kProxyChallenge, OK),
13113 TestRound(kGetProxy, kProxyChallenge, OK),
13114 TestRound(kGetProxyAuth, kServerChallenge, OK),
13115 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213116 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113117 {__LINE__,
13118 nullptr,
asankac93076192016-10-03 15:46:0213119 AUTH_NONE,
13120 OK,
13121 kSecureServer,
13122 AUTH_NONE,
13123 OK,
13124 1,
13125 0,
13126 {TestRound(kGet, kSuccess, OK)}},
13127 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113128 {__LINE__,
13129 nullptr,
asankac93076192016-10-03 15:46:0213130 AUTH_NONE,
13131 OK,
13132 kSecureServer,
13133 AUTH_SYNC,
13134 OK,
13135 2,
13136 0,
13137 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513138 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113139 {__LINE__,
13140 nullptr,
asankac93076192016-10-03 15:46:0213141 AUTH_NONE,
13142 OK,
13143 kSecureServer,
13144 AUTH_SYNC,
13145 ERR_INVALID_AUTH_CREDENTIALS,
13146 2,
13147 0,
asankae2257db2016-10-11 22:03:1613148 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113149 {__LINE__,
13150 nullptr,
asankac93076192016-10-03 15:46:0213151 AUTH_NONE,
13152 OK,
13153 kSecureServer,
13154 AUTH_ASYNC,
13155 OK,
13156 2,
13157 0,
13158 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513159 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113160 {__LINE__,
13161 nullptr,
asankac93076192016-10-03 15:46:0213162 AUTH_NONE,
13163 OK,
13164 kSecureServer,
13165 AUTH_ASYNC,
13166 ERR_INVALID_AUTH_CREDENTIALS,
13167 2,
13168 0,
asankae2257db2016-10-11 22:03:1613169 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213170 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113171 {__LINE__,
13172 kProxy,
asankac93076192016-10-03 15:46:0213173 AUTH_NONE,
13174 OK,
13175 kSecureServer,
13176 AUTH_NONE,
13177 OK,
13178 1,
13179 0,
13180 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13181 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113182 {__LINE__,
13183 kProxy,
asankac93076192016-10-03 15:46:0213184 AUTH_NONE,
13185 OK,
13186 kSecureServer,
13187 AUTH_SYNC,
13188 OK,
13189 2,
13190 0,
13191 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513192 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113193 {__LINE__,
13194 kProxy,
asankac93076192016-10-03 15:46:0213195 AUTH_NONE,
13196 OK,
13197 kSecureServer,
13198 AUTH_SYNC,
13199 ERR_INVALID_AUTH_CREDENTIALS,
13200 2,
13201 0,
13202 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613203 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113204 {__LINE__,
13205 kProxy,
asankac93076192016-10-03 15:46:0213206 AUTH_NONE,
13207 OK,
13208 kSecureServer,
13209 AUTH_ASYNC,
13210 OK,
13211 2,
13212 0,
13213 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513214 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113215 {__LINE__,
13216 kProxy,
asankac93076192016-10-03 15:46:0213217 AUTH_NONE,
13218 OK,
13219 kSecureServer,
13220 AUTH_ASYNC,
13221 ERR_INVALID_AUTH_CREDENTIALS,
13222 2,
13223 0,
13224 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613225 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213226 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113227 {__LINE__,
13228 kProxy,
asankac93076192016-10-03 15:46:0213229 AUTH_SYNC,
13230 OK,
13231 kSecureServer,
13232 AUTH_NONE,
13233 OK,
13234 2,
13235 1,
13236 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513237 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113238 {__LINE__,
13239 kProxy,
asankac93076192016-10-03 15:46:0213240 AUTH_SYNC,
13241 ERR_INVALID_AUTH_CREDENTIALS,
13242 kSecureServer,
13243 AUTH_NONE,
13244 OK,
13245 2,
13246 kNoSSL,
13247 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613248 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113249 {__LINE__,
13250 kProxy,
asankae2257db2016-10-11 22:03:1613251 AUTH_SYNC,
13252 ERR_UNSUPPORTED_AUTH_SCHEME,
13253 kSecureServer,
13254 AUTH_NONE,
13255 OK,
13256 2,
13257 kNoSSL,
13258 {TestRound(kConnect, kProxyChallenge, OK),
13259 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113260 {__LINE__,
13261 kProxy,
asankae2257db2016-10-11 22:03:1613262 AUTH_SYNC,
13263 ERR_UNEXPECTED,
13264 kSecureServer,
13265 AUTH_NONE,
13266 OK,
13267 2,
13268 kNoSSL,
13269 {TestRound(kConnect, kProxyChallenge, OK),
13270 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113271 {__LINE__,
13272 kProxy,
asankac93076192016-10-03 15:46:0213273 AUTH_ASYNC,
13274 OK,
13275 kSecureServer,
13276 AUTH_NONE,
13277 OK,
13278 2,
13279 1,
13280 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513281 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113282 {__LINE__,
13283 kProxy,
asankac93076192016-10-03 15:46:0213284 AUTH_ASYNC,
13285 ERR_INVALID_AUTH_CREDENTIALS,
13286 kSecureServer,
13287 AUTH_NONE,
13288 OK,
13289 2,
13290 kNoSSL,
13291 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613292 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213293 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113294 {__LINE__,
13295 kProxy,
asankac93076192016-10-03 15:46:0213296 AUTH_SYNC,
13297 OK,
13298 kSecureServer,
13299 AUTH_SYNC,
13300 OK,
13301 3,
13302 1,
13303 {TestRound(kConnect, kProxyChallenge, OK),
13304 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13305 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513306 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113307 {__LINE__,
13308 kProxy,
asankac93076192016-10-03 15:46:0213309 AUTH_SYNC,
13310 OK,
13311 kSecureServer,
13312 AUTH_SYNC,
13313 ERR_INVALID_AUTH_CREDENTIALS,
13314 3,
13315 1,
13316 {TestRound(kConnect, kProxyChallenge, OK),
13317 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13318 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613319 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113320 {__LINE__,
13321 kProxy,
asankac93076192016-10-03 15:46:0213322 AUTH_ASYNC,
13323 OK,
13324 kSecureServer,
13325 AUTH_SYNC,
13326 OK,
13327 3,
13328 1,
13329 {TestRound(kConnect, kProxyChallenge, OK),
13330 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13331 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513332 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113333 {__LINE__,
13334 kProxy,
asankac93076192016-10-03 15:46:0213335 AUTH_ASYNC,
13336 OK,
13337 kSecureServer,
13338 AUTH_SYNC,
13339 ERR_INVALID_AUTH_CREDENTIALS,
13340 3,
13341 1,
13342 {TestRound(kConnect, kProxyChallenge, OK),
13343 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13344 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613345 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113346 {__LINE__,
13347 kProxy,
asankac93076192016-10-03 15:46:0213348 AUTH_SYNC,
13349 OK,
13350 kSecureServer,
13351 AUTH_ASYNC,
13352 OK,
13353 3,
13354 1,
13355 {TestRound(kConnect, kProxyChallenge, OK),
13356 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13357 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513358 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113359 {__LINE__,
13360 kProxy,
asankac93076192016-10-03 15:46:0213361 AUTH_SYNC,
13362 OK,
13363 kSecureServer,
13364 AUTH_ASYNC,
13365 ERR_INVALID_AUTH_CREDENTIALS,
13366 3,
13367 1,
13368 {TestRound(kConnect, kProxyChallenge, OK),
13369 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13370 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613371 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113372 {__LINE__,
13373 kProxy,
asankac93076192016-10-03 15:46:0213374 AUTH_ASYNC,
13375 OK,
13376 kSecureServer,
13377 AUTH_ASYNC,
13378 OK,
13379 3,
13380 1,
13381 {TestRound(kConnect, kProxyChallenge, OK),
13382 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13383 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513384 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113385 {__LINE__,
13386 kProxy,
asankac93076192016-10-03 15:46:0213387 AUTH_ASYNC,
13388 OK,
13389 kSecureServer,
13390 AUTH_ASYNC,
13391 ERR_INVALID_AUTH_CREDENTIALS,
13392 3,
13393 1,
13394 {TestRound(kConnect, kProxyChallenge, OK),
13395 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13396 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613397 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113398 {__LINE__,
13399 kProxy,
13400 AUTH_ASYNC,
13401 ERR_INVALID_AUTH_CREDENTIALS,
13402 kSecureServer,
13403 AUTH_ASYNC,
13404 ERR_INVALID_AUTH_CREDENTIALS,
13405 4,
13406 2,
13407 {TestRound(kConnect, kProxyChallenge, OK),
13408 TestRound(kConnect, kProxyChallenge, OK),
13409 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13410 &kServerChallenge),
13411 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513412 };
13413
asanka463ca4262016-11-16 02:34:3113414 for (const auto& test_config : test_configs) {
13415 SCOPED_TRACE(::testing::Message() << "Test config at "
13416 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813417 HttpAuthHandlerMock::Factory* auth_factory(
13418 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713419 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913420 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613421
13422 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513423 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113424 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813425 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13426 std::string auth_challenge = "Mock realm=proxy";
13427 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413428 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13429 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813430 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013431 empty_ssl_info, origin,
13432 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813433 auth_handler->SetGenerateExpectation(
13434 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113435 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813436 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13437 }
[email protected]044de0642010-06-17 10:42:1513438 }
13439 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013440 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513441 std::string auth_challenge = "Mock realm=server";
13442 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413443 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13444 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513445 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013446 empty_ssl_info, origin,
13447 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513448 auth_handler->SetGenerateExpectation(
13449 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113450 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813451 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613452
13453 // The second handler always succeeds. It should only be used where there
13454 // are multiple auth sessions for server auth in the same network
13455 // transaction using the same auth scheme.
13456 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913457 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613458 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13459 empty_ssl_info, origin,
13460 NetLogWithSource());
13461 second_handler->SetGenerateExpectation(true, OK);
13462 auth_factory->AddMockHandler(second_handler.release(),
13463 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513464 }
13465 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913466 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913467 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13468 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513469 } else {
Bence Béky53a5aef2018-03-29 21:54:1213470 session_deps_.proxy_resolution_service =
13471 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513472 }
13473
13474 HttpRequestInfo request;
13475 request.method = "GET";
13476 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1013477 request.traffic_annotation =
13478 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513479
danakj1fd259a02016-04-16 03:17:0913480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513481
rchcb68dc62015-05-21 04:45:3613482 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13483
13484 std::vector<std::vector<MockRead>> mock_reads(1);
13485 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513486 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213487 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513488 const TestRound& read_write_round = test_config.rounds[round];
13489
13490 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613491 mock_reads.back().push_back(read_write_round.read);
13492 mock_writes.back().push_back(read_write_round.write);
13493
13494 // kProxyChallenge uses Proxy-Connection: close which means that the
13495 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413496 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613497 mock_reads.push_back(std::vector<MockRead>());
13498 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513499 }
13500
rchcb68dc62015-05-21 04:45:3613501 if (read_write_round.extra_read) {
13502 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513503 }
rchcb68dc62015-05-21 04:45:3613504 if (read_write_round.extra_write) {
13505 mock_writes.back().push_back(*read_write_round.extra_write);
13506 }
[email protected]044de0642010-06-17 10:42:1513507
13508 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513509 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713510 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513511 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613512 }
[email protected]044de0642010-06-17 10:42:1513513
danakj1fd259a02016-04-16 03:17:0913514 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613515 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913516 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413517 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813518 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613519 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213520 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613521 }
13522
mmenkecc2298e2015-12-07 18:20:1813523 // Transaction must be created after DataProviders, so it's destroyed before
13524 // they are as well.
13525 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13526
rchcb68dc62015-05-21 04:45:3613527 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213528 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613529 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513530 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113531 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513532 int rv;
13533 if (round == 0) {
tfarina42834112016-09-22 13:38:2013534 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513535 } else {
[email protected]49639fa2011-12-20 23:22:4113536 rv = trans.RestartWithAuth(
13537 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513538 }
13539 if (rv == ERR_IO_PENDING)
13540 rv = callback.WaitForResult();
13541
13542 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613543 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013544 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513545 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513546 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13547 continue;
13548 }
13549 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213550 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513551 } else {
wezca1070932016-05-26 20:30:5213552 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613553 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513554 }
13555 }
[email protected]e5ae96a2010-04-14 20:12:4513556 }
13557}
13558
bncd16676a2016-07-20 16:23:0113559TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413560 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413561 HttpAuthHandlerMock::Factory* auth_factory(
13562 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713563 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1213564 session_deps_.proxy_resolution_service =
13565 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713566 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13567 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413568
13569 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13570 auth_handler->set_connection_based(true);
13571 std::string auth_challenge = "Mock realm=server";
13572 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413573 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13574 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913575 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413576 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013577 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813578 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413579
[email protected]c871bce92010-07-15 21:51:1413580 int rv = OK;
13581 const HttpResponseInfo* response = NULL;
13582 HttpRequestInfo request;
13583 request.method = "GET";
13584 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1013585 request.traffic_annotation =
13586 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713587
danakj1fd259a02016-04-16 03:17:0913588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013589
13590 // Use a TCP Socket Pool with only one connection per group. This is used
13591 // to validate that the TCP socket is not released to the pool between
13592 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213593 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813594 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013595 50, // Max sockets for pool
13596 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113597 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13598 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913599 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213600 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813601 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013602
bnc691fda62016-08-12 00:43:1613603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113604 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413605
13606 const MockWrite kGet(
13607 "GET / HTTP/1.1\r\n"
13608 "Host: www.example.com\r\n"
13609 "Connection: keep-alive\r\n\r\n");
13610 const MockWrite kGetAuth(
13611 "GET / HTTP/1.1\r\n"
13612 "Host: www.example.com\r\n"
13613 "Connection: keep-alive\r\n"
13614 "Authorization: auth_token\r\n\r\n");
13615
13616 const MockRead kServerChallenge(
13617 "HTTP/1.1 401 Unauthorized\r\n"
13618 "WWW-Authenticate: Mock realm=server\r\n"
13619 "Content-Type: text/html; charset=iso-8859-1\r\n"
13620 "Content-Length: 14\r\n\r\n"
13621 "Unauthorized\r\n");
13622 const MockRead kSuccess(
13623 "HTTP/1.1 200 OK\r\n"
13624 "Content-Type: text/html; charset=iso-8859-1\r\n"
13625 "Content-Length: 3\r\n\r\n"
13626 "Yes");
13627
13628 MockWrite writes[] = {
13629 // First round
13630 kGet,
13631 // Second round
13632 kGetAuth,
13633 // Third round
13634 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013635 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013636 kGetAuth,
13637 // Competing request
13638 kGet,
[email protected]c871bce92010-07-15 21:51:1413639 };
13640 MockRead reads[] = {
13641 // First round
13642 kServerChallenge,
13643 // Second round
13644 kServerChallenge,
13645 // Third round
[email protected]eca50e122010-09-11 14:03:3013646 kServerChallenge,
13647 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413648 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013649 // Competing response
13650 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413651 };
13652 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13653 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713654 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413655
thestig9d3bb0c2015-01-24 00:49:5113656 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013657
13658 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413659 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013660 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413661 if (rv == ERR_IO_PENDING)
13662 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113663 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613664 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213665 ASSERT_TRUE(response);
13666 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813667 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113668 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13669 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413670
[email protected]7ef4cbbb2011-02-06 11:19:1013671 // In between rounds, another request comes in for the same domain.
13672 // It should not be able to grab the TCP socket that trans has already
13673 // claimed.
bnc691fda62016-08-12 00:43:1613674 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113675 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013676 rv = trans_compete.Start(&request, callback_compete.callback(),
13677 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013679 // callback_compete.WaitForResult at this point would stall forever,
13680 // since the HttpNetworkTransaction does not release the request back to
13681 // the pool until after authentication completes.
13682
13683 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413684 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613685 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413686 if (rv == ERR_IO_PENDING)
13687 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113688 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613689 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213690 ASSERT_TRUE(response);
13691 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813692 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113693 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13694 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413695
[email protected]7ef4cbbb2011-02-06 11:19:1013696 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413697 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613698 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413699 if (rv == ERR_IO_PENDING)
13700 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113701 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613702 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213703 ASSERT_TRUE(response);
13704 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813705 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113706 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13707 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013708
[email protected]7ef4cbbb2011-02-06 11:19:1013709 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013710 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613711 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013712 if (rv == ERR_IO_PENDING)
13713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113714 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613715 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213716 ASSERT_TRUE(response);
13717 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813718 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013719
asanka463ca4262016-11-16 02:34:3113720 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13721 // auth handler should transition to a DONE state in concert with the remote
13722 // server. But that's not something we can test here with a mock handler.
13723 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13724 auth_handler->state());
13725
[email protected]7ef4cbbb2011-02-06 11:19:1013726 // Read the body since the fourth round was successful. This will also
13727 // release the socket back to the pool.
13728 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613729 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013730 if (rv == ERR_IO_PENDING)
13731 rv = callback.WaitForResult();
13732 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613733 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013734 EXPECT_EQ(0, rv);
13735 // There are still 0 idle sockets, since the trans_compete transaction
13736 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813737 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013738
13739 // The competing request can now finish. Wait for the headers and then
13740 // read the body.
13741 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113742 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613743 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013744 if (rv == ERR_IO_PENDING)
13745 rv = callback.WaitForResult();
13746 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613747 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013748 EXPECT_EQ(0, rv);
13749
13750 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813751 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413752}
13753
[email protected]65041fa2010-05-21 06:56:5313754// This tests the case that a request is issued via http instead of spdy after
13755// npn is negotiated.
bncd16676a2016-07-20 16:23:0113756TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313757 HttpRequestInfo request;
13758 request.method = "GET";
bncce36dca22015-04-21 22:11:2313759 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013760 request.traffic_annotation =
13761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313762
13763 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313764 MockWrite(
13765 "GET / HTTP/1.1\r\n"
13766 "Host: www.example.org\r\n"
13767 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313768 };
13769
13770 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213771 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313772 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213773 MockRead("\r\n"),
13774 MockRead("hello world"),
13775 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313776 };
13777
[email protected]8ddf8322012-02-23 18:08:0613778 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613779 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313780
[email protected]bb88e1d32013-05-03 23:11:0713781 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313782
13783 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13784 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713785 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313786
[email protected]49639fa2011-12-20 23:22:4113787 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313788
danakj1fd259a02016-04-16 03:17:0913789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313791
tfarina42834112016-09-22 13:38:2013792 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313793
robpercival214763f2016-07-01 23:27:0113794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13795 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313796
bnc691fda62016-08-12 00:43:1613797 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213798 ASSERT_TRUE(response);
13799 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313800 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13801
13802 std::string response_data;
bnc691fda62016-08-12 00:43:1613803 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313804 EXPECT_EQ("hello world", response_data);
13805
13806 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213807 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313808}
[email protected]26ef6582010-06-24 02:30:4713809
bnc55ff9da2015-08-19 18:42:3513810// Simulate the SSL handshake completing with an NPN negotiation followed by an
13811// immediate server closing of the socket.
13812// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113813TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713814 HttpRequestInfo request;
13815 request.method = "GET";
bncce36dca22015-04-21 22:11:2313816 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013817 request.traffic_annotation =
13818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713819
[email protected]8ddf8322012-02-23 18:08:0613820 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613821 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713822 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713823
Bence Béky27ad0a12018-02-08 00:35:4813824 SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113825 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713826
13827 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613828 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713829 };
13830
rch8e6c6c42015-05-01 14:05:1313831 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13832 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713833 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713834
[email protected]49639fa2011-12-20 23:22:4113835 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713836
danakj1fd259a02016-04-16 03:17:0913837 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613838 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713839
tfarina42834112016-09-22 13:38:2013840 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13842 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713843}
[email protected]65d34382010-07-01 18:12:2613844
[email protected]795cbf82013-07-22 09:37:2713845// A subclass of HttpAuthHandlerMock that records the request URL when
13846// it gets it. This is needed since the auth handler may get destroyed
13847// before we get a chance to query it.
13848class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13849 public:
13850 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13851
Chris Watkins7a41d3552017-12-01 02:13:2713852 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713853
13854 protected:
dchengb03027d2014-10-21 12:00:2013855 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13856 const HttpRequestInfo* request,
13857 const CompletionCallback& callback,
13858 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713859 *url_ = request->url;
13860 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13861 credentials, request, callback, auth_token);
13862 }
13863
13864 private:
13865 GURL* url_;
13866};
13867
[email protected]8e6441ca2010-08-19 05:56:3813868// Test that if we cancel the transaction as the connection is completing, that
13869// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113870TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813871 // Setup everything about the connection to complete synchronously, so that
13872 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13873 // for is the callback from the HttpStreamRequest.
13874 // Then cancel the transaction.
13875 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613876 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813877 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613878 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13879 MockRead(SYNCHRONOUS, "hello world"),
13880 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813881 };
13882
[email protected]8e6441ca2010-08-19 05:56:3813883 HttpRequestInfo request;
13884 request.method = "GET";
bncce36dca22015-04-21 22:11:2313885 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013886 request.traffic_annotation =
13887 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813888
[email protected]bb88e1d32013-05-03 23:11:0713889 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913890 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813891 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913892 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713893
[email protected]8e6441ca2010-08-19 05:56:3813894 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13895 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713896 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813897
[email protected]49639fa2011-12-20 23:22:4113898 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813899
vishal.b62985ca92015-04-17 08:45:5113900 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113901 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813903 trans.reset(); // Cancel the transaction here.
13904
fdoray92e35a72016-06-10 15:54:5513905 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013906}
13907
[email protected]ecab6e052014-05-16 14:58:1213908// Test that if a transaction is cancelled after receiving the headers, the
13909// stream is drained properly and added back to the socket pool. The main
13910// purpose of this test is to make sure that an HttpStreamParser can be read
13911// from after the HttpNetworkTransaction and the objects it owns have been
13912// deleted.
13913// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113914TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213915 MockRead data_reads[] = {
13916 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13917 MockRead(ASYNC, "Content-Length: 2\r\n"),
13918 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13919 MockRead(ASYNC, "1"),
13920 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13921 // HttpNetworkTransaction has been deleted.
13922 MockRead(ASYNC, "2"),
13923 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13924 };
13925 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13926 session_deps_.socket_factory->AddSocketDataProvider(&data);
13927
danakj1fd259a02016-04-16 03:17:0913928 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213929
13930 {
13931 HttpRequestInfo request;
13932 request.method = "GET";
bncce36dca22015-04-21 22:11:2313933 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013934 request.traffic_annotation =
13935 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213936
dcheng48459ac22014-08-26 00:46:4113937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213938 TestCompletionCallback callback;
13939
tfarina42834112016-09-22 13:38:2013940 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213942 callback.WaitForResult();
13943
13944 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213945 ASSERT_TRUE(response);
13946 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213947 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13948
13949 // The transaction and HttpRequestInfo are deleted.
13950 }
13951
13952 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513953 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213954
13955 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113956 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213957}
13958
[email protected]76a505b2010-08-25 06:23:0013959// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113960TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913961 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913962 ProxyResolutionService::CreateFixedFromPacResult(
13963 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113964 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713965 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013967
[email protected]76a505b2010-08-25 06:23:0013968 HttpRequestInfo request;
13969 request.method = "GET";
bncce36dca22015-04-21 22:11:2313970 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013971 request.traffic_annotation =
13972 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013973
13974 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313975 MockWrite(
13976 "GET http://www.example.org/ HTTP/1.1\r\n"
13977 "Host: www.example.org\r\n"
13978 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013979 };
13980
13981 MockRead data_reads1[] = {
13982 MockRead("HTTP/1.1 200 OK\r\n"),
13983 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13984 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613985 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013986 };
13987
13988 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13989 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713990 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013991
[email protected]49639fa2011-12-20 23:22:4113992 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013993
bnc691fda62016-08-12 00:43:1613994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913995 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613996 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913997 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13998 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013999
bnc691fda62016-08-12 00:43:1614000 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014002
14003 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114004 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014005
bnc691fda62016-08-12 00:43:1614006 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214007 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014008
14009 EXPECT_TRUE(response->headers->IsKeepAlive());
14010 EXPECT_EQ(200, response->headers->response_code());
14011 EXPECT_EQ(100, response->headers->GetContentLength());
14012 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714013 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14014 HostPortPair::FromString("myproxy:70")),
14015 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914016 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14017 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14018 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014019 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014020
14021 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614022 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014023 TestLoadTimingNotReusedWithPac(load_timing_info,
14024 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014025}
14026
14027// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114028TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914029 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914030 ProxyResolutionService::CreateFixedFromPacResult(
14031 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114032 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714033 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014035
[email protected]76a505b2010-08-25 06:23:0014036 HttpRequestInfo request;
14037 request.method = "GET";
bncce36dca22015-04-21 22:11:2314038 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014039 request.traffic_annotation =
14040 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014041
14042 // Since we have proxy, should try to establish tunnel.
14043 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714044 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14045 "Host: www.example.org:443\r\n"
14046 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014047
rsleevidb16bb02015-11-12 23:47:1714048 MockWrite("GET / HTTP/1.1\r\n"
14049 "Host: www.example.org\r\n"
14050 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014051 };
14052
14053 MockRead data_reads1[] = {
14054 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14055
14056 MockRead("HTTP/1.1 200 OK\r\n"),
14057 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14058 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614059 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014060 };
14061
14062 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14063 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714064 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614065 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714066 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014067
[email protected]49639fa2011-12-20 23:22:4114068 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014069
bnc691fda62016-08-12 00:43:1614070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914071 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614072 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914073 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14074 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014075
bnc691fda62016-08-12 00:43:1614076 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014078
14079 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114080 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614081 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014082 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014083 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014084 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14085 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014086 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014087 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014088 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14089 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014090
bnc691fda62016-08-12 00:43:1614091 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214092 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014093
14094 EXPECT_TRUE(response->headers->IsKeepAlive());
14095 EXPECT_EQ(200, response->headers->response_code());
14096 EXPECT_EQ(100, response->headers->GetContentLength());
14097 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14098 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714099 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14100 HostPortPair::FromString("myproxy:70")),
14101 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914102 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14103 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14104 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014105
14106 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614107 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014108 TestLoadTimingNotReusedWithPac(load_timing_info,
14109 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014110}
14111
rsleevidb16bb02015-11-12 23:47:1714112// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14113// literal host.
bncd16676a2016-07-20 16:23:0114114TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914115 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914116 ProxyResolutionService::CreateFixedFromPacResult(
14117 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714118 BoundTestNetLog log;
14119 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914120 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714121
14122 HttpRequestInfo request;
14123 request.method = "GET";
14124 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014125 request.traffic_annotation =
14126 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714127
14128 // Since we have proxy, should try to establish tunnel.
14129 MockWrite data_writes1[] = {
14130 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
14131 "Host: [::1]:443\r\n"
14132 "Proxy-Connection: keep-alive\r\n\r\n"),
14133
14134 MockWrite("GET / HTTP/1.1\r\n"
14135 "Host: [::1]\r\n"
14136 "Connection: keep-alive\r\n\r\n"),
14137 };
14138
14139 MockRead data_reads1[] = {
14140 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14141
14142 MockRead("HTTP/1.1 200 OK\r\n"),
14143 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14144 MockRead("Content-Length: 100\r\n\r\n"),
14145 MockRead(SYNCHRONOUS, OK),
14146 };
14147
14148 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14149 data_writes1, arraysize(data_writes1));
14150 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14151 SSLSocketDataProvider ssl(ASYNC, OK);
14152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14153
14154 TestCompletionCallback callback1;
14155
bnc691fda62016-08-12 00:43:1614156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714157
bnc691fda62016-08-12 00:43:1614158 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114159 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714160
14161 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114162 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714163 TestNetLogEntry::List entries;
14164 log.GetEntries(&entries);
14165 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014166 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14167 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714168 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014169 entries, pos,
14170 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14171 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714172
bnc691fda62016-08-12 00:43:1614173 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214174 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714175
14176 EXPECT_TRUE(response->headers->IsKeepAlive());
14177 EXPECT_EQ(200, response->headers->response_code());
14178 EXPECT_EQ(100, response->headers->GetContentLength());
14179 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14180 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714181 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14182 HostPortPair::FromString("myproxy:70")),
14183 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714184
14185 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614186 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714187 TestLoadTimingNotReusedWithPac(load_timing_info,
14188 CONNECT_TIMING_HAS_SSL_TIMES);
14189}
14190
[email protected]76a505b2010-08-25 06:23:0014191// Test a basic HTTPS GET request through a proxy, but the server hangs up
14192// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114193TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914194 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14195 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114196 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714197 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914198 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014199
[email protected]76a505b2010-08-25 06:23:0014200 HttpRequestInfo request;
14201 request.method = "GET";
bncce36dca22015-04-21 22:11:2314202 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014203 request.traffic_annotation =
14204 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014205
14206 // Since we have proxy, should try to establish tunnel.
14207 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714208 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14209 "Host: www.example.org:443\r\n"
14210 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014211
rsleevidb16bb02015-11-12 23:47:1714212 MockWrite("GET / HTTP/1.1\r\n"
14213 "Host: www.example.org\r\n"
14214 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014215 };
14216
14217 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014218 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614219 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014220 };
14221
14222 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14223 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714224 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614225 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014227
[email protected]49639fa2011-12-20 23:22:4114228 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014229
bnc691fda62016-08-12 00:43:1614230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014231
bnc691fda62016-08-12 00:43:1614232 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014234
14235 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114236 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614237 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014238 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014239 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014240 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14241 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014242 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014243 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014244 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14245 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014246}
14247
[email protected]749eefa82010-09-13 22:14:0314248// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114249TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114250 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914251 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114252 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314253
bnc42331402016-07-25 13:36:1514254 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114255 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314256 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114257 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314258 };
14259
rch8e6c6c42015-05-01 14:05:1314260 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
14261 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714262 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314263
[email protected]8ddf8322012-02-23 18:08:0614264 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614265 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314267
danakj1fd259a02016-04-16 03:17:0914268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314269
14270 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314271 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014272 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414273 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714274 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214275 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314276
14277 HttpRequestInfo request;
14278 request.method = "GET";
bncce36dca22015-04-21 22:11:2314279 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014280 request.traffic_annotation =
14281 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314282
14283 // This is the important line that marks this as a preconnect.
14284 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14285
bnc691fda62016-08-12 00:43:1614286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314287
[email protected]41d64e82013-07-03 22:44:2614288 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014289 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114290 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14291 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314292}
14293
[email protected]73b8dd222010-11-11 19:55:2414294// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614295// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214296void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714297 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914298 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714299 request_info.url = GURL("https://www.example.com/");
14300 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914301 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014302 request_info.traffic_annotation =
14303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714304
[email protected]8ddf8322012-02-23 18:08:0614305 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914306 MockWrite data_writes[] = {
14307 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414308 };
ttuttle859dc7a2015-04-23 19:42:2914309 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0714310 session_deps_.socket_factory->AddSocketDataProvider(&data);
14311 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414312
danakj1fd259a02016-04-16 03:17:0914313 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614314 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414315
[email protected]49639fa2011-12-20 23:22:4114316 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014317 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914318 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414319 rv = callback.WaitForResult();
14320 ASSERT_EQ(error, rv);
14321}
14322
bncd16676a2016-07-20 16:23:0114323TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414324 // Just check a grab bag of cert errors.
14325 static const int kErrors[] = {
14326 ERR_CERT_COMMON_NAME_INVALID,
14327 ERR_CERT_AUTHORITY_INVALID,
14328 ERR_CERT_DATE_INVALID,
14329 };
14330 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614331 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14332 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414333 }
14334}
14335
[email protected]bd0b6772011-01-11 19:59:3014336// Ensure that a client certificate is removed from the SSL client auth
14337// cache when:
14338// 1) No proxy is involved.
14339// 2) TLS False Start is disabled.
14340// 3) The initial TLS handshake requests a client certificate.
14341// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114342TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914343 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714344 request_info.url = GURL("https://www.example.com/");
14345 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914346 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014347 request_info.traffic_annotation =
14348 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714349
[email protected]bd0b6772011-01-11 19:59:3014350 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114351 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014352
14353 // [ssl_]data1 contains the data for the first SSL handshake. When a
14354 // CertificateRequest is received for the first time, the handshake will
14355 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914356 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014357 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914359 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714360 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014361
14362 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14363 // False Start is not being used, the result of the SSL handshake will be
14364 // returned as part of the SSLClientSocket::Connect() call. This test
14365 // matches the result of a server sending a handshake_failure alert,
14366 // rather than a Finished message, because it requires a client
14367 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914368 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014369 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714370 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914371 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714372 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014373
14374 // [ssl_]data3 contains the data for the third SSL handshake. When a
14375 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214376 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14377 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014378 // of the HttpNetworkTransaction. Because this test failure is due to
14379 // requiring a client certificate, this fallback handshake should also
14380 // fail.
ttuttle859dc7a2015-04-23 19:42:2914381 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014382 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914384 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714385 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014386
[email protected]80c75f682012-05-26 16:22:1714387 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14388 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214389 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14390 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714391 // of the HttpNetworkTransaction. Because this test failure is due to
14392 // requiring a client certificate, this fallback handshake should also
14393 // fail.
ttuttle859dc7a2015-04-23 19:42:2914394 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714395 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914397 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714398 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714399
danakj1fd259a02016-04-16 03:17:0914400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614401 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014402
[email protected]bd0b6772011-01-11 19:59:3014403 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114404 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014405 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114406 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014407
14408 // Complete the SSL handshake, which should abort due to requiring a
14409 // client certificate.
14410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114411 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014412
14413 // Indicate that no certificate should be supplied. From the perspective
14414 // of SSLClientCertCache, NULL is just as meaningful as a real
14415 // certificate, so this is the same as supply a
14416 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614417 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114418 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014419
14420 // Ensure the certificate was added to the client auth cache before
14421 // allowing the connection to continue restarting.
14422 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414423 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114424 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414425 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214426 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014427
14428 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714429 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14430 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014431 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114432 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014433
14434 // Ensure that the client certificate is removed from the cache on a
14435 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114436 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414437 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014438}
14439
14440// Ensure that a client certificate is removed from the SSL client auth
14441// cache when:
14442// 1) No proxy is involved.
14443// 2) TLS False Start is enabled.
14444// 3) The initial TLS handshake requests a client certificate.
14445// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114446TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914447 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714448 request_info.url = GURL("https://www.example.com/");
14449 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914450 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014451 request_info.traffic_annotation =
14452 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714453
[email protected]bd0b6772011-01-11 19:59:3014454 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114455 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014456
14457 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14458 // return successfully after reading up to the peer's Certificate message.
14459 // This is to allow the caller to call SSLClientSocket::Write(), which can
14460 // enqueue application data to be sent in the same packet as the
14461 // ChangeCipherSpec and Finished messages.
14462 // The actual handshake will be finished when SSLClientSocket::Read() is
14463 // called, which expects to process the peer's ChangeCipherSpec and
14464 // Finished messages. If there was an error negotiating with the peer,
14465 // such as due to the peer requiring a client certificate when none was
14466 // supplied, the alert sent by the peer won't be processed until Read() is
14467 // called.
14468
14469 // Like the non-False Start case, when a client certificate is requested by
14470 // the peer, the handshake is aborted during the Connect() call.
14471 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914472 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014473 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714474 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914475 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714476 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014477
14478 // When a client certificate is supplied, Connect() will not be aborted
14479 // when the peer requests the certificate. Instead, the handshake will
14480 // artificially succeed, allowing the caller to write the HTTP request to
14481 // the socket. The handshake messages are not processed until Read() is
14482 // called, which then detects that the handshake was aborted, due to the
14483 // peer sending a handshake_failure because it requires a client
14484 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914485 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014486 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914488 MockRead data2_reads[] = {
14489 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014490 };
ttuttle859dc7a2015-04-23 19:42:2914491 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714492 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014493
14494 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714495 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14496 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914497 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014498 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714499 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914500 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714501 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014502
[email protected]80c75f682012-05-26 16:22:1714503 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14504 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914505 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714506 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914508 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714509 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714510
[email protected]7799de12013-05-30 05:52:5114511 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914512 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114513 ssl_data5.cert_request_info = cert_request.get();
14514 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914515 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114516 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14517
danakj1fd259a02016-04-16 03:17:0914518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614519 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014520
[email protected]bd0b6772011-01-11 19:59:3014521 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114522 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014523 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114524 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014525
14526 // Complete the SSL handshake, which should abort due to requiring a
14527 // client certificate.
14528 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114529 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014530
14531 // Indicate that no certificate should be supplied. From the perspective
14532 // of SSLClientCertCache, NULL is just as meaningful as a real
14533 // certificate, so this is the same as supply a
14534 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614535 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114536 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014537
14538 // Ensure the certificate was added to the client auth cache before
14539 // allowing the connection to continue restarting.
14540 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414541 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114542 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414543 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214544 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014545
[email protected]bd0b6772011-01-11 19:59:3014546 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714547 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14548 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014549 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114550 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014551
14552 // Ensure that the client certificate is removed from the cache on a
14553 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114554 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414555 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014556}
14557
[email protected]8c405132011-01-11 22:03:1814558// Ensure that a client certificate is removed from the SSL client auth
14559// cache when:
14560// 1) An HTTPS proxy is involved.
14561// 3) The HTTPS proxy requests a client certificate.
14562// 4) The client supplies an invalid/unacceptable certificate for the
14563// proxy.
14564// The test is repeated twice, first for connecting to an HTTPS endpoint,
14565// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114566TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914567 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14568 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114569 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714570 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814571
14572 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114573 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814574
14575 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14576 // [ssl_]data[1-3]. Rather than represending the endpoint
14577 // (www.example.com:443), they represent failures with the HTTPS proxy
14578 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914579 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814580 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714581 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914582 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714583 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814584
ttuttle859dc7a2015-04-23 19:42:2914585 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814586 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914588 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714589 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814590
[email protected]80c75f682012-05-26 16:22:1714591 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14592#if 0
ttuttle859dc7a2015-04-23 19:42:2914593 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814594 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914596 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714597 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714598#endif
[email protected]8c405132011-01-11 22:03:1814599
ttuttle859dc7a2015-04-23 19:42:2914600 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814601 requests[0].url = GURL("https://www.example.com/");
14602 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914603 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014604 requests[0].traffic_annotation =
14605 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814606
14607 requests[1].url = GURL("http://www.example.com/");
14608 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914609 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014610 requests[1].traffic_annotation =
14611 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814612
14613 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714614 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914615 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814617
14618 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114619 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014620 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114621 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814622
14623 // Complete the SSL handshake, which should abort due to requiring a
14624 // client certificate.
14625 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114626 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814627
14628 // Indicate that no certificate should be supplied. From the perspective
14629 // of SSLClientCertCache, NULL is just as meaningful as a real
14630 // certificate, so this is the same as supply a
14631 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614632 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114633 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814634
14635 // Ensure the certificate was added to the client auth cache before
14636 // allowing the connection to continue restarting.
14637 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414638 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114639 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414640 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214641 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814642 // Ensure the certificate was NOT cached for the endpoint. This only
14643 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114644 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414645 HostPortPair("www.example.com", 443), &client_cert,
14646 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814647
14648 // Restart the handshake. This will consume ssl_data2, which fails, and
14649 // then consume ssl_data3, which should also fail. The result code is
14650 // checked against what ssl_data3 should return.
14651 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114652 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814653
14654 // Now that the new handshake has failed, ensure that the client
14655 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114656 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414657 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114658 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414659 HostPortPair("www.example.com", 443), &client_cert,
14660 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814661 }
14662}
14663
bncd16676a2016-07-20 16:23:0114664TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614665 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914666 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914667 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614668
bnc032658ba2016-09-26 18:17:1514669 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614670
bncdf80d44fd2016-07-15 20:27:4114671 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914672 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814673 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114674 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714675 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614676 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114677 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614678 };
bnc42331402016-07-25 13:36:1514679 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114680 SpdySerializedFrame host1_resp_body(
14681 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514682 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114683 SpdySerializedFrame host2_resp_body(
14684 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614685 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114686 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14687 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314688 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614689 };
14690
eroman36d84e54432016-03-17 03:23:0214691 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214692 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314693 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14694 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714695 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614696
[email protected]aa22b242011-11-16 18:58:2914697 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614698 HttpRequestInfo request1;
14699 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314700 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614701 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014702 request1.traffic_annotation =
14703 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014704 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614705
tfarina42834112016-09-22 13:38:2014706 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14708 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614709
14710 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214711 ASSERT_TRUE(response);
14712 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214713 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614714
14715 std::string response_data;
robpercival214763f2016-07-01 23:27:0114716 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614717 EXPECT_EQ("hello!", response_data);
14718
bnca4d611d2016-09-22 19:55:3714719 // Preload mail.example.com into HostCache.
14720 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014721 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614722 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014723 std::unique_ptr<HostResolver::Request> request;
14724 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14725 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014726 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714728 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114729 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614730
14731 HttpRequestInfo request2;
14732 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714733 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614734 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014735 request2.traffic_annotation =
14736 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014737 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614738
tfarina42834112016-09-22 13:38:2014739 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14741 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614742
14743 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214744 ASSERT_TRUE(response);
14745 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214746 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614747 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214748 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114749 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614750 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614751}
14752
bncd16676a2016-07-20 16:23:0114753TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214754 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914755 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214757
bnc032658ba2016-09-26 18:17:1514758 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214759
bncdf80d44fd2016-07-15 20:27:4114760 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914761 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814762 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114763 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714764 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214765 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114766 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214767 };
bnc42331402016-07-25 13:36:1514768 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114769 SpdySerializedFrame host1_resp_body(
14770 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514771 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114772 SpdySerializedFrame host2_resp_body(
14773 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214774 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114775 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14776 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314777 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214778 };
14779
eroman36d84e54432016-03-17 03:23:0214780 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214781 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314782 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14783 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714784 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214785
14786 TestCompletionCallback callback;
14787 HttpRequestInfo request1;
14788 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314789 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214790 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014791 request1.traffic_annotation =
14792 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014793 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214794
tfarina42834112016-09-22 13:38:2014795 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14797 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214798
14799 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214800 ASSERT_TRUE(response);
14801 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214802 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214803
14804 std::string response_data;
robpercival214763f2016-07-01 23:27:0114805 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214806 EXPECT_EQ("hello!", response_data);
14807
14808 HttpRequestInfo request2;
14809 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714810 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214811 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014812 request2.traffic_annotation =
14813 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014814 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214815
tfarina42834112016-09-22 13:38:2014816 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14818 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214819
14820 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214821 ASSERT_TRUE(response);
14822 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214823 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214824 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214825 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114826 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214827 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214828}
14829
bnc8016c1f2017-03-31 02:11:2914830// Regression test for https://crbug.com/546991.
14831// The server might not be able to serve an IP pooled request, and might send a
14832// 421 Misdirected Request response status to indicate this.
14833// HttpNetworkTransaction should reset the request and retry without IP pooling.
14834TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14835 // Two hosts resolve to the same IP address.
14836 const std::string ip_addr = "1.2.3.4";
14837 IPAddress ip;
14838 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14839 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14840
Jeremy Roman0579ed62017-08-29 15:56:1914841 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914842 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14843 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14844
14845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14846
14847 // Two requests on the first connection.
14848 SpdySerializedFrame req1(
14849 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14850 spdy_util_.UpdateWithStreamDestruction(1);
14851 SpdySerializedFrame req2(
14852 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14853 SpdySerializedFrame rst(
14854 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14855 MockWrite writes1[] = {
14856 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14857 CreateMockWrite(rst, 6),
14858 };
14859
14860 // The first one succeeds, the second gets error 421 Misdirected Request.
14861 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14862 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14863 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714864 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914865 SpdySerializedFrame resp2(
14866 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14867 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14868 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14869
14870 MockConnect connect1(ASYNC, OK, peer_addr);
14871 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14872 arraysize(writes1));
14873 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14874
14875 AddSSLSocketData();
14876
14877 // Retry the second request on a second connection.
14878 SpdyTestUtil spdy_util2;
14879 SpdySerializedFrame req3(
14880 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14881 MockWrite writes2[] = {
14882 CreateMockWrite(req3, 0),
14883 };
14884
14885 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14886 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14887 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14888 MockRead(ASYNC, 0, 3)};
14889
14890 MockConnect connect2(ASYNC, OK, peer_addr);
14891 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14892 arraysize(writes2));
14893 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14894
14895 AddSSLSocketData();
14896
14897 // Preload mail.example.org into HostCache.
14898 HostPortPair host_port("mail.example.org", 443);
14899 HostResolver::RequestInfo resolve_info(host_port);
14900 AddressList ignored;
14901 std::unique_ptr<HostResolver::Request> request;
14902 TestCompletionCallback callback;
14903 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14904 &ignored, callback.callback(),
14905 &request, NetLogWithSource());
14906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14907 rv = callback.WaitForResult();
14908 EXPECT_THAT(rv, IsOk());
14909
14910 HttpRequestInfo request1;
14911 request1.method = "GET";
14912 request1.url = GURL("https://www.example.org/");
14913 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014914 request1.traffic_annotation =
14915 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914916 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14917
14918 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14920 rv = callback.WaitForResult();
14921 EXPECT_THAT(rv, IsOk());
14922
14923 const HttpResponseInfo* response = trans1.GetResponseInfo();
14924 ASSERT_TRUE(response);
14925 ASSERT_TRUE(response->headers);
14926 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14927 EXPECT_TRUE(response->was_fetched_via_spdy);
14928 EXPECT_TRUE(response->was_alpn_negotiated);
14929 std::string response_data;
14930 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14931 EXPECT_EQ("hello!", response_data);
14932
14933 HttpRequestInfo request2;
14934 request2.method = "GET";
14935 request2.url = GURL("https://mail.example.org/");
14936 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014937 request2.traffic_annotation =
14938 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914939 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14940
14941 BoundTestNetLog log;
14942 rv = trans2.Start(&request2, callback.callback(), log.bound());
14943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14944 rv = callback.WaitForResult();
14945 EXPECT_THAT(rv, IsOk());
14946
14947 response = trans2.GetResponseInfo();
14948 ASSERT_TRUE(response);
14949 ASSERT_TRUE(response->headers);
14950 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14951 EXPECT_TRUE(response->was_fetched_via_spdy);
14952 EXPECT_TRUE(response->was_alpn_negotiated);
14953 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14954 EXPECT_EQ("hello!", response_data);
14955
14956 TestNetLogEntry::List entries;
14957 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914958 ExpectLogContainsSomewhere(
14959 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914960 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914961}
14962
14963// Test that HTTP 421 responses are properly returned to the caller if received
14964// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14965// portions of the response.
14966TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14967 // Two hosts resolve to the same IP address.
14968 const std::string ip_addr = "1.2.3.4";
14969 IPAddress ip;
14970 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14971 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14972
Jeremy Roman0579ed62017-08-29 15:56:1914973 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914974 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14975 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14976
14977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14978
14979 // Two requests on the first connection.
14980 SpdySerializedFrame req1(
14981 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14982 spdy_util_.UpdateWithStreamDestruction(1);
14983 SpdySerializedFrame req2(
14984 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14985 SpdySerializedFrame rst(
14986 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14987 MockWrite writes1[] = {
14988 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14989 CreateMockWrite(rst, 6),
14990 };
14991
14992 // The first one succeeds, the second gets error 421 Misdirected Request.
14993 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14994 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14995 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714996 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914997 SpdySerializedFrame resp2(
14998 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14999 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15000 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15001
15002 MockConnect connect1(ASYNC, OK, peer_addr);
15003 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
15004 arraysize(writes1));
15005 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15006
15007 AddSSLSocketData();
15008
15009 // Retry the second request on a second connection. It returns 421 Misdirected
15010 // Retry again.
15011 SpdyTestUtil spdy_util2;
15012 SpdySerializedFrame req3(
15013 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15014 MockWrite writes2[] = {
15015 CreateMockWrite(req3, 0),
15016 };
15017
15018 SpdySerializedFrame resp3(
15019 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
15020 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
15021 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15022 MockRead(ASYNC, 0, 3)};
15023
15024 MockConnect connect2(ASYNC, OK, peer_addr);
15025 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
15026 arraysize(writes2));
15027 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15028
15029 AddSSLSocketData();
15030
15031 // Preload mail.example.org into HostCache.
15032 HostPortPair host_port("mail.example.org", 443);
15033 HostResolver::RequestInfo resolve_info(host_port);
15034 AddressList ignored;
15035 std::unique_ptr<HostResolver::Request> request;
15036 TestCompletionCallback callback;
15037 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15038 &ignored, callback.callback(),
15039 &request, NetLogWithSource());
15040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15041 rv = callback.WaitForResult();
15042 EXPECT_THAT(rv, IsOk());
15043
15044 HttpRequestInfo request1;
15045 request1.method = "GET";
15046 request1.url = GURL("https://www.example.org/");
15047 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015048 request1.traffic_annotation =
15049 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915050 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15051
15052 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15053 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15054 rv = callback.WaitForResult();
15055 EXPECT_THAT(rv, IsOk());
15056
15057 const HttpResponseInfo* response = trans1.GetResponseInfo();
15058 ASSERT_TRUE(response);
15059 ASSERT_TRUE(response->headers);
15060 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15061 EXPECT_TRUE(response->was_fetched_via_spdy);
15062 EXPECT_TRUE(response->was_alpn_negotiated);
15063 std::string response_data;
15064 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15065 EXPECT_EQ("hello!", response_data);
15066
15067 HttpRequestInfo request2;
15068 request2.method = "GET";
15069 request2.url = GURL("https://mail.example.org/");
15070 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015071 request2.traffic_annotation =
15072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915073 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15074
15075 BoundTestNetLog log;
15076 rv = trans2.Start(&request2, callback.callback(), log.bound());
15077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15078 rv = callback.WaitForResult();
15079 EXPECT_THAT(rv, IsOk());
15080
15081 // After a retry, the 421 Misdirected Request is reported back up to the
15082 // caller.
15083 response = trans2.GetResponseInfo();
15084 ASSERT_TRUE(response);
15085 ASSERT_TRUE(response->headers);
15086 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15087 EXPECT_TRUE(response->was_fetched_via_spdy);
15088 EXPECT_TRUE(response->was_alpn_negotiated);
15089 EXPECT_TRUE(response->ssl_info.cert);
15090 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15091 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915092}
15093
bnc6dcd8192017-05-25 20:11:5015094class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4615095 public:
15096 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5015097 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2715098 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4615099
dchengb03027d2014-10-21 12:00:2015100 int ResolveFromCache(const RequestInfo& info,
15101 AddressList* addresses,
tfarina42834112016-09-22 13:38:2015102 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5015103 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4015104 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5015105 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4615106 return rv;
15107 }
15108
[email protected]e3ceb682011-06-28 23:55:4615109 private:
[email protected]e3ceb682011-06-28 23:55:4615110 const HostPortPair host_port_;
15111};
15112
bncd16676a2016-07-20 16:23:0115113TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315114 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4615115 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915116 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3715117 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0915118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615119
bnc032658ba2016-09-26 18:17:1515120 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615121
bncdf80d44fd2016-07-15 20:27:4115122 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915123 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815124 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4115125 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715126 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615127 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115128 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615129 };
bnc42331402016-07-25 13:36:1515130 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115131 SpdySerializedFrame host1_resp_body(
15132 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1515133 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115134 SpdySerializedFrame host2_resp_body(
15135 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615136 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115137 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15138 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315139 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615140 };
15141
eroman36d84e54432016-03-17 03:23:0215142 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215143 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1315144 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
15145 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0715146 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615147
[email protected]aa22b242011-11-16 18:58:2915148 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615149 HttpRequestInfo request1;
15150 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315151 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615152 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015153 request1.traffic_annotation =
15154 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015155 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615156
tfarina42834112016-09-22 13:38:2015157 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15159 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615160
15161 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215162 ASSERT_TRUE(response);
15163 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215164 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615165
15166 std::string response_data;
robpercival214763f2016-07-01 23:27:0115167 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615168 EXPECT_EQ("hello!", response_data);
15169
15170 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715171 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615172 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015173 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015174 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15175 &ignored, callback.callback(),
15176 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715178 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115179 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615180
15181 HttpRequestInfo request2;
15182 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715183 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615184 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015185 request2.traffic_annotation =
15186 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015187 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615188
tfarina42834112016-09-22 13:38:2015189 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115190 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15191 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615192
15193 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215194 ASSERT_TRUE(response);
15195 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215196 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615197 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215198 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115199 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615200 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615201}
15202
bncd16676a2016-07-20 16:23:0115203TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315204 const std::string https_url = "https://www.example.org:8080/";
15205 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415206
15207 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115208 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915209 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415210
15211 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115212 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415213 };
15214
bnc42331402016-07-25 13:36:1515215 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115216 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15217 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915218 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415219
rch8e6c6c42015-05-01 14:05:1315220 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15221 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415222 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715223 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415224
15225 // HTTP GET for the HTTP URL
15226 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315227 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415228 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315229 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415230 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415231 };
15232
15233 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315234 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15235 MockRead(ASYNC, 2, "hello"),
15236 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415237 };
15238
rch8e6c6c42015-05-01 14:05:1315239 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15240 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0415241
[email protected]8450d722012-07-02 19:14:0415242 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615243 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15246 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415247
danakj1fd259a02016-04-16 03:17:0915248 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415249
15250 // Start the first transaction to set up the SpdySession
15251 HttpRequestInfo request1;
15252 request1.method = "GET";
15253 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415254 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015255 request1.traffic_annotation =
15256 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015257 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415258 TestCompletionCallback callback1;
15259 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015260 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515261 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415262
robpercival214763f2016-07-01 23:27:0115263 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415264 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15265
15266 // Now, start the HTTP request
15267 HttpRequestInfo request2;
15268 request2.method = "GET";
15269 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415270 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015271 request2.traffic_annotation =
15272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015273 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415274 TestCompletionCallback callback2;
15275 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015276 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515277 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415278
robpercival214763f2016-07-01 23:27:0115279 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415280 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15281}
15282
bnc5452e2a2015-05-08 16:27:4215283// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15284// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115285TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515286 url::SchemeHostPort server("https", "www.example.org", 443);
15287 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215288
bnc8bef8da22016-05-30 01:28:2515289 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215290 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615291 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15293
15294 // No data should be read from the alternative, because HTTP/1.1 is
15295 // negotiated.
15296 StaticSocketDataProvider data;
15297 session_deps_.socket_factory->AddSocketDataProvider(&data);
15298
15299 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615300 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215301 // mocked. This way the request relies on the alternate Job.
15302 StaticSocketDataProvider data_refused;
15303 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15304 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15305
zhongyi3d4a55e72016-04-22 20:36:4615306 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915307 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015308 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215309 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115310 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215311 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115312 http_server_properties->SetHttp2AlternativeService(
15313 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215314
bnc5452e2a2015-05-08 16:27:4215315 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615316 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215317 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515318 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015319 request.traffic_annotation =
15320 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215321 TestCompletionCallback callback;
15322
15323 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215324 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015325 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215326 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215327}
15328
bnc40448a532015-05-11 19:13:1415329// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615330// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415331// succeeds, the request should succeed, even if the latter fails because
15332// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115333TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515334 url::SchemeHostPort server("https", "www.example.org", 443);
15335 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415336
15337 // Negotiate HTTP/1.1 with alternative.
15338 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615339 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415340 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15341
15342 // No data should be read from the alternative, because HTTP/1.1 is
15343 // negotiated.
15344 StaticSocketDataProvider data;
15345 session_deps_.socket_factory->AddSocketDataProvider(&data);
15346
zhongyi3d4a55e72016-04-22 20:36:4615347 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415348 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615349 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415350 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15351
15352 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515353 MockWrite("GET / HTTP/1.1\r\n"
15354 "Host: www.example.org\r\n"
15355 "Connection: keep-alive\r\n\r\n"),
15356 MockWrite("GET /second HTTP/1.1\r\n"
15357 "Host: www.example.org\r\n"
15358 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415359 };
15360
15361 MockRead http_reads[] = {
15362 MockRead("HTTP/1.1 200 OK\r\n"),
15363 MockRead("Content-Type: text/html\r\n"),
15364 MockRead("Content-Length: 6\r\n\r\n"),
15365 MockRead("foobar"),
15366 MockRead("HTTP/1.1 200 OK\r\n"),
15367 MockRead("Content-Type: text/html\r\n"),
15368 MockRead("Content-Length: 7\r\n\r\n"),
15369 MockRead("another"),
15370 };
15371 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15372 http_writes, arraysize(http_writes));
15373 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15374
zhongyi3d4a55e72016-04-22 20:36:4615375 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015377 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415378 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115379 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215380 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115381 http_server_properties->SetHttp2AlternativeService(
15382 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415383
15384 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15385 HttpRequestInfo request1;
15386 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515387 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415388 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015389 request1.traffic_annotation =
15390 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415391 TestCompletionCallback callback1;
15392
tfarina42834112016-09-22 13:38:2015393 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415394 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115395 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415396
15397 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215398 ASSERT_TRUE(response1);
15399 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415400 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15401
15402 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115403 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415404 EXPECT_EQ("foobar", response_data1);
15405
15406 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15407 // for alternative service.
15408 EXPECT_TRUE(
15409 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15410
zhongyi3d4a55e72016-04-22 20:36:4615411 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415412 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615413 // to server.
bnc40448a532015-05-11 19:13:1415414 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15415 HttpRequestInfo request2;
15416 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515417 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415418 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015419 request2.traffic_annotation =
15420 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415421 TestCompletionCallback callback2;
15422
tfarina42834112016-09-22 13:38:2015423 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415424 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115425 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415426
15427 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215428 ASSERT_TRUE(response2);
15429 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415430 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15431
15432 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115433 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415434 EXPECT_EQ("another", response_data2);
15435}
15436
bnc5452e2a2015-05-08 16:27:4215437// Alternative service requires HTTP/2 (or SPDY), but there is already a
15438// HTTP/1.1 socket open to the alternative server. That socket should not be
15439// used.
bncd16676a2016-07-20 16:23:0115440TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615441 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215442 HostPortPair alternative("alternative.example.org", 443);
15443 std::string origin_url = "https://origin.example.org:443";
15444 std::string alternative_url = "https://alternative.example.org:443";
15445
15446 // Negotiate HTTP/1.1 with alternative.example.org.
15447 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615448 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15450
15451 // HTTP/1.1 data for |request1| and |request2|.
15452 MockWrite http_writes[] = {
15453 MockWrite(
15454 "GET / HTTP/1.1\r\n"
15455 "Host: alternative.example.org\r\n"
15456 "Connection: keep-alive\r\n\r\n"),
15457 MockWrite(
15458 "GET / HTTP/1.1\r\n"
15459 "Host: alternative.example.org\r\n"
15460 "Connection: keep-alive\r\n\r\n"),
15461 };
15462
15463 MockRead http_reads[] = {
15464 MockRead(
15465 "HTTP/1.1 200 OK\r\n"
15466 "Content-Type: text/html; charset=iso-8859-1\r\n"
15467 "Content-Length: 40\r\n\r\n"
15468 "first HTTP/1.1 response from alternative"),
15469 MockRead(
15470 "HTTP/1.1 200 OK\r\n"
15471 "Content-Type: text/html; charset=iso-8859-1\r\n"
15472 "Content-Length: 41\r\n\r\n"
15473 "second HTTP/1.1 response from alternative"),
15474 };
15475 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15476 http_writes, arraysize(http_writes));
15477 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15478
15479 // This test documents that an alternate Job should not pool to an already
15480 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615481 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215482 StaticSocketDataProvider data_refused;
15483 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15484 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15485
zhongyi3d4a55e72016-04-22 20:36:4615486 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015488 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215489 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115490 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215491 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115492 http_server_properties->SetHttp2AlternativeService(
15493 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215494
15495 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215496 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615497 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215498 request1.method = "GET";
15499 request1.url = GURL(alternative_url);
15500 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015501 request1.traffic_annotation =
15502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215503 TestCompletionCallback callback1;
15504
tfarina42834112016-09-22 13:38:2015505 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115506 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615507 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215508 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215509 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215510 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215511 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215512 EXPECT_FALSE(response1->was_fetched_via_spdy);
15513 std::string response_data1;
bnc691fda62016-08-12 00:43:1615514 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215515 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15516
15517 // Request for origin.example.org, which has an alternative service. This
15518 // will start two Jobs: the alternative looks for connections to pool to,
15519 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615520 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215521 // this request fails.
bnc5452e2a2015-05-08 16:27:4215522 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615523 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215524 request2.method = "GET";
15525 request2.url = GURL(origin_url);
15526 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015527 request2.traffic_annotation =
15528 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215529 TestCompletionCallback callback2;
15530
tfarina42834112016-09-22 13:38:2015531 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115532 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215533
15534 // Another transaction to alternative. This is to test that the HTTP/1.1
15535 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215536 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615537 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215538 request3.method = "GET";
15539 request3.url = GURL(alternative_url);
15540 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015541 request3.traffic_annotation =
15542 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215543 TestCompletionCallback callback3;
15544
tfarina42834112016-09-22 13:38:2015545 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115546 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615547 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215548 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215549 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215550 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215551 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215552 EXPECT_FALSE(response3->was_fetched_via_spdy);
15553 std::string response_data3;
bnc691fda62016-08-12 00:43:1615554 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215555 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15556}
15557
bncd16676a2016-07-20 16:23:0115558TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315559 const std::string https_url = "https://www.example.org:8080/";
15560 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415561
rdsmithebb50aa2015-11-12 03:44:3815562 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115563 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815564
[email protected]8450d722012-07-02 19:14:0415565 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315566 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115567 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415568 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115569 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915570 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115571 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215572 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915573
15574 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915575 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715576 req2_block[kHttp2MethodHeader] = "GET";
15577 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15578 req2_block[kHttp2SchemeHeader] = "http";
15579 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115580 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515581 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415582
15583 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115584 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15585 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415586 };
15587
bncdf80d44fd2016-07-15 20:27:4115588 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515589 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115590 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515591 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115592 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15593 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815594 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115595 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815596 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515597 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115598 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315599 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115600 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315601 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115602 CreateMockRead(wrapped_resp1, 4),
15603 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315604 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115605 CreateMockRead(resp2, 8),
15606 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315607 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15608 };
[email protected]8450d722012-07-02 19:14:0415609
mmenke666a6fea2015-12-19 04:16:3315610 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15611 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415612 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715613 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415614
Lily Houghton8c2f97d2018-01-22 05:06:5915615 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915616 ProxyResolutionService::CreateFixedFromPacResult(
15617 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115618 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715619 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415620 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615621 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415623 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615624 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15626 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415627
danakj1fd259a02016-04-16 03:17:0915628 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415629
15630 // Start the first transaction to set up the SpdySession
15631 HttpRequestInfo request1;
15632 request1.method = "GET";
15633 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415634 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015635 request1.traffic_annotation =
15636 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015637 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415638 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015639 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415640
mmenke666a6fea2015-12-19 04:16:3315641 // This pause is a hack to avoid running into https://crbug.com/497228.
15642 data1.RunUntilPaused();
15643 base::RunLoop().RunUntilIdle();
15644 data1.Resume();
robpercival214763f2016-07-01 23:27:0115645 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415646 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15647
[email protected]f6c63db52013-02-02 00:35:2215648 LoadTimingInfo load_timing_info1;
15649 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15650 TestLoadTimingNotReusedWithPac(load_timing_info1,
15651 CONNECT_TIMING_HAS_SSL_TIMES);
15652
mmenke666a6fea2015-12-19 04:16:3315653 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415654 HttpRequestInfo request2;
15655 request2.method = "GET";
15656 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415657 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015658 request2.traffic_annotation =
15659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015660 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415661 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015662 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415663
mmenke666a6fea2015-12-19 04:16:3315664 // This pause is a hack to avoid running into https://crbug.com/497228.
15665 data1.RunUntilPaused();
15666 base::RunLoop().RunUntilIdle();
15667 data1.Resume();
robpercival214763f2016-07-01 23:27:0115668 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315669
[email protected]8450d722012-07-02 19:14:0415670 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215671
15672 LoadTimingInfo load_timing_info2;
15673 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15674 // The established SPDY sessions is considered reused by the HTTP request.
15675 TestLoadTimingReusedWithPac(load_timing_info2);
15676 // HTTP requests over a SPDY session should have a different connection
15677 // socket_log_id than requests over a tunnel.
15678 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415679}
15680
[email protected]2d88e7d2012-07-19 17:55:1715681// Test that in the case where we have a SPDY session to a SPDY proxy
15682// that we do not pool other origins that resolve to the same IP when
15683// the certificate does not match the new origin.
15684// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115685TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315686 const std::string url1 = "http://www.example.org/";
15687 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715688 const std::string ip_addr = "1.2.3.4";
15689
rdsmithebb50aa2015-11-12 03:44:3815690 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115691 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815692
[email protected]2d88e7d2012-07-19 17:55:1715693 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615694 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315695 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115696 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515697 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715698
15699 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115700 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715701 };
15702
bnc42331402016-07-25 13:36:1515703 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115704 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715705 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115706 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15707 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715708 };
15709
mmenke666a6fea2015-12-19 04:16:3315710 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15711 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215712 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915713 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715714 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15715 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315716 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715717
15718 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115719 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915720 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715721
15722 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115723 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715724 };
15725
bnc42331402016-07-25 13:36:1515726 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115727 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15728 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315729 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715730
mmenke666a6fea2015-12-19 04:16:3315731 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15732 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715733 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315734 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715735
15736 // Set up a proxy config that sends HTTP requests to a proxy, and
15737 // all others direct.
15738 ProxyConfig proxy_config;
15739 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915740 session_deps_.proxy_resolution_service =
15741 std::make_unique<ProxyResolutionService>(
15742 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15743 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15744 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715745
bncce36dca22015-04-21 22:11:2315746 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615747 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715748 // Load a valid cert. Note, that this does not need to
15749 // be valid for proxy because the MockSSLClientSocket does
15750 // not actually verify it. But SpdySession will use this
15751 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915752 ssl1.ssl_info.cert =
15753 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15754 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15756 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715757
15758 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615759 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15761 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715762
Jeremy Roman0579ed62017-08-29 15:56:1915763 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315764 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715765 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715766
danakj1fd259a02016-04-16 03:17:0915767 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715768
15769 // Start the first transaction to set up the SpdySession
15770 HttpRequestInfo request1;
15771 request1.method = "GET";
15772 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715773 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015774 request1.traffic_annotation =
15775 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015776 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715777 TestCompletionCallback callback1;
15778 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015779 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315780 // This pause is a hack to avoid running into https://crbug.com/497228.
15781 data1.RunUntilPaused();
15782 base::RunLoop().RunUntilIdle();
15783 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715784
robpercival214763f2016-07-01 23:27:0115785 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715786 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15787
15788 // Now, start the HTTP request
15789 HttpRequestInfo request2;
15790 request2.method = "GET";
15791 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715792 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015793 request2.traffic_annotation =
15794 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015795 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715796 TestCompletionCallback callback2;
15797 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015798 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515799 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715800
15801 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115802 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715803 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15804}
15805
[email protected]85f97342013-04-17 06:12:2415806// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15807// error) in SPDY session, removes the socket from pool and closes the SPDY
15808// session. Verify that new url's from the same HttpNetworkSession (and a new
15809// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115810TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315811 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415812
15813 MockRead reads1[] = {
15814 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15815 };
15816
mmenke11eb5152015-06-09 14:50:5015817 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415818
bncdf80d44fd2016-07-15 20:27:4115819 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915820 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415821 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115822 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415823 };
15824
bnc42331402016-07-25 13:36:1515825 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115826 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415827 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115828 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15829 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415830 };
15831
mmenke11eb5152015-06-09 14:50:5015832 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15833 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415834
[email protected]85f97342013-04-17 06:12:2415835 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615836 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15838 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415839
15840 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615841 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015842 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15843 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415844
danakj1fd259a02016-04-16 03:17:0915845 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015846 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415847
15848 // Start the first transaction to set up the SpdySession and verify that
15849 // connection was closed.
15850 HttpRequestInfo request1;
15851 request1.method = "GET";
15852 request1.url = GURL(https_url);
15853 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015854 request1.traffic_annotation =
15855 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015856 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415857 TestCompletionCallback callback1;
15858 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015859 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115860 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415861
15862 // Now, start the second request and make sure it succeeds.
15863 HttpRequestInfo request2;
15864 request2.method = "GET";
15865 request2.url = GURL(https_url);
15866 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015867 request2.traffic_annotation =
15868 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015869 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415870 TestCompletionCallback callback2;
15871 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015872 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415873
robpercival214763f2016-07-01 23:27:0115874 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415875 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15876}
15877
bncd16676a2016-07-20 16:23:0115878TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315879 ClientSocketPoolManager::set_max_sockets_per_group(
15880 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15881 ClientSocketPoolManager::set_max_sockets_per_pool(
15882 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15883
15884 // Use two different hosts with different IPs so they don't get pooled.
15885 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15886 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315888
15889 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615890 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315891 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615892 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15895
bncdf80d44fd2016-07-15 20:27:4115896 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915897 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315898 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115899 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315900 };
bnc42331402016-07-25 13:36:1515901 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115902 SpdySerializedFrame host1_resp_body(
15903 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315904 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115905 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915906 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315907 };
15908
rdsmithebb50aa2015-11-12 03:44:3815909 // Use a separate test instance for the separate SpdySession that will be
15910 // created.
bncd16676a2016-07-20 16:23:0115911 SpdyTestUtil spdy_util_2;
Bence Béky53a5aef2018-03-29 21:54:1215912 SequencedSocketData spdy1_data(spdy1_reads, arraysize(spdy1_reads),
15913 spdy1_writes, arraysize(spdy1_writes));
15914 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0315915
bncdf80d44fd2016-07-15 20:27:4115916 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915917 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315918 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115919 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315920 };
bnc42331402016-07-25 13:36:1515921 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115922 SpdySerializedFrame host2_resp_body(
15923 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315924 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115925 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915926 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315927 };
15928
Bence Béky53a5aef2018-03-29 21:54:1215929 SequencedSocketData spdy2_data(spdy2_reads, arraysize(spdy2_reads),
15930 spdy2_writes, arraysize(spdy2_writes));
15931 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0315932
15933 MockWrite http_write[] = {
15934 MockWrite("GET / HTTP/1.1\r\n"
15935 "Host: www.a.com\r\n"
15936 "Connection: keep-alive\r\n\r\n"),
15937 };
15938
15939 MockRead http_read[] = {
15940 MockRead("HTTP/1.1 200 OK\r\n"),
15941 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15942 MockRead("Content-Length: 6\r\n\r\n"),
15943 MockRead("hello!"),
15944 };
15945 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15946 http_write, arraysize(http_write));
15947 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15948
15949 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415950 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15951 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315952 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615953 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315954
15955 TestCompletionCallback callback;
15956 HttpRequestInfo request1;
15957 request1.method = "GET";
15958 request1.url = GURL("https://www.a.com/");
15959 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015960 request1.traffic_annotation =
15961 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815962 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915963 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315964
tfarina42834112016-09-22 13:38:2015965 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15967 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315968
15969 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215970 ASSERT_TRUE(response);
15971 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215972 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315973 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215974 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315975
15976 std::string response_data;
robpercival214763f2016-07-01 23:27:0115977 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315978 EXPECT_EQ("hello!", response_data);
15979 trans.reset();
15980 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615981 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315982
15983 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415984 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15985 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315986 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615987 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315988 HttpRequestInfo request2;
15989 request2.method = "GET";
15990 request2.url = GURL("https://www.b.com/");
15991 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015992 request2.traffic_annotation =
15993 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815994 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915995 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315996
tfarina42834112016-09-22 13:38:2015997 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15999 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316000
16001 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216002 ASSERT_TRUE(response);
16003 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216004 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316005 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216006 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116007 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316008 EXPECT_EQ("hello!", response_data);
16009 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616010 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316011 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616012 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316013
16014 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0416015 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
16016 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0316017 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616018 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316019 HttpRequestInfo request3;
16020 request3.method = "GET";
16021 request3.url = GURL("http://www.a.com/");
16022 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016023 request3.traffic_annotation =
16024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816025 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916026 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316027
tfarina42834112016-09-22 13:38:2016028 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16030 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316031
16032 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216033 ASSERT_TRUE(response);
16034 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316035 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16036 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216037 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116038 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316039 EXPECT_EQ("hello!", response_data);
16040 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616041 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316042 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616043 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316044}
16045
bncd16676a2016-07-20 16:23:0116046TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416047 HttpRequestInfo request;
16048 request.method = "GET";
bncce36dca22015-04-21 22:11:2316049 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016050 request.traffic_annotation =
16051 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416052
danakj1fd259a02016-04-16 03:17:0916053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616054 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416055
ttuttled9dbc652015-09-29 20:00:5916056 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416057 StaticSocketDataProvider data;
16058 data.set_connect_data(mock_connect);
16059 session_deps_.socket_factory->AddSocketDataProvider(&data);
16060
16061 TestCompletionCallback callback;
16062
tfarina42834112016-09-22 13:38:2016063 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416065
16066 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116067 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416068
[email protected]79e1fd62013-06-20 06:50:0416069 // We don't care whether this succeeds or fails, but it shouldn't crash.
16070 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616071 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716072
16073 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616074 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716075 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116076 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916077
16078 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616079 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916080 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416081}
16082
bncd16676a2016-07-20 16:23:0116083TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416084 HttpRequestInfo request;
16085 request.method = "GET";
bncce36dca22015-04-21 22:11:2316086 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016087 request.traffic_annotation =
16088 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416089
danakj1fd259a02016-04-16 03:17:0916090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416092
ttuttled9dbc652015-09-29 20:00:5916093 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416094 StaticSocketDataProvider data;
16095 data.set_connect_data(mock_connect);
16096 session_deps_.socket_factory->AddSocketDataProvider(&data);
16097
16098 TestCompletionCallback callback;
16099
tfarina42834112016-09-22 13:38:2016100 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416102
16103 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116104 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416105
[email protected]79e1fd62013-06-20 06:50:0416106 // We don't care whether this succeeds or fails, but it shouldn't crash.
16107 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616108 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716109
16110 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616111 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716112 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116113 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916114
16115 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616116 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916117 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416118}
16119
bncd16676a2016-07-20 16:23:0116120TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416121 HttpRequestInfo request;
16122 request.method = "GET";
bncce36dca22015-04-21 22:11:2316123 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016124 request.traffic_annotation =
16125 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416126
danakj1fd259a02016-04-16 03:17:0916127 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416129
16130 MockWrite data_writes[] = {
16131 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16132 };
16133 MockRead data_reads[] = {
16134 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16135 };
16136
16137 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16138 data_writes, arraysize(data_writes));
16139 session_deps_.socket_factory->AddSocketDataProvider(&data);
16140
16141 TestCompletionCallback callback;
16142
tfarina42834112016-09-22 13:38:2016143 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116144 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416145
16146 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116147 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416148
[email protected]79e1fd62013-06-20 06:50:0416149 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616150 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416151 EXPECT_TRUE(request_headers.HasHeader("Host"));
16152}
16153
bncd16676a2016-07-20 16:23:0116154TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416155 HttpRequestInfo request;
16156 request.method = "GET";
bncce36dca22015-04-21 22:11:2316157 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016158 request.traffic_annotation =
16159 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416160
danakj1fd259a02016-04-16 03:17:0916161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416163
16164 MockWrite data_writes[] = {
16165 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16166 };
16167 MockRead data_reads[] = {
16168 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16169 };
16170
16171 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16172 data_writes, arraysize(data_writes));
16173 session_deps_.socket_factory->AddSocketDataProvider(&data);
16174
16175 TestCompletionCallback callback;
16176
tfarina42834112016-09-22 13:38:2016177 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416179
16180 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116181 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416182
[email protected]79e1fd62013-06-20 06:50:0416183 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616184 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416185 EXPECT_TRUE(request_headers.HasHeader("Host"));
16186}
16187
bncd16676a2016-07-20 16:23:0116188TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416189 HttpRequestInfo request;
16190 request.method = "GET";
bncce36dca22015-04-21 22:11:2316191 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016192 request.traffic_annotation =
16193 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416194
danakj1fd259a02016-04-16 03:17:0916195 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616196 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416197
16198 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316199 MockWrite(
16200 "GET / HTTP/1.1\r\n"
16201 "Host: www.example.org\r\n"
16202 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416203 };
16204 MockRead data_reads[] = {
16205 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16206 };
16207
16208 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16209 data_writes, arraysize(data_writes));
16210 session_deps_.socket_factory->AddSocketDataProvider(&data);
16211
16212 TestCompletionCallback callback;
16213
tfarina42834112016-09-22 13:38:2016214 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416216
16217 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116218 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416219
[email protected]79e1fd62013-06-20 06:50:0416220 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616221 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416222 EXPECT_TRUE(request_headers.HasHeader("Host"));
16223}
16224
bncd16676a2016-07-20 16:23:0116225TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416226 HttpRequestInfo request;
16227 request.method = "GET";
bncce36dca22015-04-21 22:11:2316228 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016229 request.traffic_annotation =
16230 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416231
danakj1fd259a02016-04-16 03:17:0916232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416234
16235 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316236 MockWrite(
16237 "GET / HTTP/1.1\r\n"
16238 "Host: www.example.org\r\n"
16239 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416240 };
16241 MockRead data_reads[] = {
16242 MockRead(ASYNC, ERR_CONNECTION_RESET),
16243 };
16244
16245 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16246 data_writes, arraysize(data_writes));
16247 session_deps_.socket_factory->AddSocketDataProvider(&data);
16248
16249 TestCompletionCallback callback;
16250
tfarina42834112016-09-22 13:38:2016251 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416253
16254 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116255 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416256
[email protected]79e1fd62013-06-20 06:50:0416257 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616258 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416259 EXPECT_TRUE(request_headers.HasHeader("Host"));
16260}
16261
bncd16676a2016-07-20 16:23:0116262TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416263 HttpRequestInfo request;
16264 request.method = "GET";
bncce36dca22015-04-21 22:11:2316265 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416266 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016267 request.traffic_annotation =
16268 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416269
danakj1fd259a02016-04-16 03:17:0916270 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616271 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416272
16273 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316274 MockWrite(
16275 "GET / HTTP/1.1\r\n"
16276 "Host: www.example.org\r\n"
16277 "Connection: keep-alive\r\n"
16278 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416279 };
16280 MockRead data_reads[] = {
16281 MockRead("HTTP/1.1 200 OK\r\n"
16282 "Content-Length: 5\r\n\r\n"
16283 "hello"),
16284 MockRead(ASYNC, ERR_UNEXPECTED),
16285 };
16286
16287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16288 data_writes, arraysize(data_writes));
16289 session_deps_.socket_factory->AddSocketDataProvider(&data);
16290
16291 TestCompletionCallback callback;
16292
tfarina42834112016-09-22 13:38:2016293 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116294 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416295
16296 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116297 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416298
16299 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616300 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416301 std::string foo;
16302 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16303 EXPECT_EQ("bar", foo);
16304}
16305
[email protected]bf828982013-08-14 18:01:4716306namespace {
16307
yhiranoa7e05bb2014-11-06 05:40:3916308// Fake HttpStream that simply records calls to SetPriority().
16309class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0316310 public base::SupportsWeakPtr<FakeStream> {
16311 public:
16312 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2716313 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0316314
16315 RequestPriority priority() const { return priority_; }
16316
dchengb03027d2014-10-21 12:00:2016317 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716318 bool can_send_early,
dchengb03027d2014-10-21 12:00:2016319 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016320 const NetLogWithSource& net_log,
Bence Békya25e3f72018-02-13 21:13:3916321 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316322 return ERR_IO_PENDING;
16323 }
16324
dchengb03027d2014-10-21 12:00:2016325 int SendRequest(const HttpRequestHeaders& request_headers,
16326 HttpResponseInfo* response,
Bence Békya25e3f72018-02-13 21:13:3916327 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316328 ADD_FAILURE();
16329 return ERR_UNEXPECTED;
16330 }
16331
Bence Békya25e3f72018-02-13 21:13:3916332 int ReadResponseHeaders(CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316333 ADD_FAILURE();
16334 return ERR_UNEXPECTED;
16335 }
16336
dchengb03027d2014-10-21 12:00:2016337 int ReadResponseBody(IOBuffer* buf,
16338 int buf_len,
Bence Békya25e3f72018-02-13 21:13:3916339 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316340 ADD_FAILURE();
16341 return ERR_UNEXPECTED;
16342 }
16343
dchengb03027d2014-10-21 12:00:2016344 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0316345
dchengb03027d2014-10-21 12:00:2016346 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0316347 ADD_FAILURE();
16348 return false;
16349 }
16350
dchengb03027d2014-10-21 12:00:2016351 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0316352 ADD_FAILURE();
16353 return false;
16354 }
16355
dchengb03027d2014-10-21 12:00:2016356 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316357
mmenkebd84c392015-09-02 14:12:3416358 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0316359
sclittle4de1bab92015-09-22 21:28:2416360 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5916361 ADD_FAILURE();
16362 return 0;
16363 }
16364
sclittlebe1ccf62015-09-02 19:40:3616365 int64_t GetTotalSentBytes() const override {
16366 ADD_FAILURE();
16367 return 0;
16368 }
16369
dchengb03027d2014-10-21 12:00:2016370 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0316371 ADD_FAILURE();
16372 return false;
16373 }
16374
rchcd379012017-04-12 21:53:3216375 bool GetAlternativeService(
16376 AlternativeService* alternative_service) const override {
16377 ADD_FAILURE();
16378 return false;
16379 }
16380
dchengb03027d2014-10-21 12:00:2016381 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
16382
16383 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0316384 ADD_FAILURE();
16385 }
16386
ttuttled9dbc652015-09-29 20:00:5916387 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16388
nharper78e6d2b2016-09-21 05:42:3516389 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16390 TokenBindingType tb_type,
16391 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416392 ADD_FAILURE();
16393 return ERR_NOT_IMPLEMENTED;
16394 }
16395
dchengb03027d2014-10-21 12:00:2016396 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316397
zhongyica364fbb2015-12-12 03:39:1216398 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16399
dchengb03027d2014-10-21 12:00:2016400 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0316401
yhiranoa7e05bb2014-11-06 05:40:3916402 HttpStream* RenewStreamForAuth() override { return NULL; }
16403
Andrey Kosyakov83a6eee2017-08-14 19:20:0416404 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
16405
[email protected]e86839fd2013-08-14 18:29:0316406 private:
16407 RequestPriority priority_;
16408
16409 DISALLOW_COPY_AND_ASSIGN(FakeStream);
16410};
16411
16412// Fake HttpStreamRequest that simply records calls to SetPriority()
16413// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4716414class FakeStreamRequest : public HttpStreamRequest,
16415 public base::SupportsWeakPtr<FakeStreamRequest> {
16416 public:
[email protected]e86839fd2013-08-14 18:29:0316417 FakeStreamRequest(RequestPriority priority,
16418 HttpStreamRequest::Delegate* delegate)
16419 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4416420 delegate_(delegate),
16421 websocket_stream_create_helper_(NULL) {}
16422
16423 FakeStreamRequest(RequestPriority priority,
16424 HttpStreamRequest::Delegate* delegate,
16425 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
16426 : priority_(priority),
16427 delegate_(delegate),
16428 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0316429
Chris Watkins7a41d3552017-12-01 02:13:2716430 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4716431
16432 RequestPriority priority() const { return priority_; }
16433
[email protected]831e4a32013-11-14 02:14:4416434 const WebSocketHandshakeStreamBase::CreateHelper*
16435 websocket_stream_create_helper() const {
16436 return websocket_stream_create_helper_;
16437 }
16438
[email protected]e86839fd2013-08-14 18:29:0316439 // Create a new FakeStream and pass it to the request's
16440 // delegate. Returns a weak pointer to the FakeStream.
16441 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1916442 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0316443 // Do this before calling OnStreamReady() as OnStreamReady() may
16444 // immediately delete |fake_stream|.
16445 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0016446 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0316447 return weak_stream;
16448 }
16449
asanka681f02d2017-02-22 17:06:3916450 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4716451 ADD_FAILURE();
16452 return ERR_UNEXPECTED;
16453 }
16454
dchengb03027d2014-10-21 12:00:2016455 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4716456 ADD_FAILURE();
16457 return LoadState();
16458 }
16459
dchengb03027d2014-10-21 12:00:2016460 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4716461
bnc94c92842016-09-21 15:22:5216462 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716463
bnc6227b26e2016-08-12 02:00:4316464 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4716465
dchengb03027d2014-10-21 12:00:2016466 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716467
ttuttle1f2d7e92015-04-28 16:17:4716468 const ConnectionAttempts& connection_attempts() const override {
16469 static ConnectionAttempts no_attempts;
16470 return no_attempts;
16471 }
16472
[email protected]bf828982013-08-14 18:01:4716473 private:
16474 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0316475 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4416476 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4716477
16478 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
16479};
16480
16481// Fake HttpStreamFactory that vends FakeStreamRequests.
16482class FakeStreamFactory : public HttpStreamFactory {
16483 public:
Chris Watkins7a41d3552017-12-01 02:13:2716484 FakeStreamFactory() = default;
16485 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4716486
16487 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
16488 // RequestStream() (which may be NULL if it was destroyed already).
16489 base::WeakPtr<FakeStreamRequest> last_stream_request() {
16490 return last_stream_request_;
16491 }
16492
xunjieli96f2a402017-06-05 17:24:2716493 std::unique_ptr<HttpStreamRequest> RequestStream(
16494 const HttpRequestInfo& info,
16495 RequestPriority priority,
16496 const SSLConfig& server_ssl_config,
16497 const SSLConfig& proxy_ssl_config,
16498 HttpStreamRequest::Delegate* delegate,
16499 bool enable_ip_based_pooling,
16500 bool enable_alternative_services,
16501 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1916502 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4716503 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716504 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716505 }
16506
xunjieli96f2a402017-06-05 17:24:2716507 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0816508 const HttpRequestInfo& info,
16509 RequestPriority priority,
16510 const SSLConfig& server_ssl_config,
16511 const SSLConfig& proxy_ssl_config,
16512 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2916513 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616514 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016515 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0816516 NOTREACHED();
16517 return nullptr;
16518 }
16519
xunjieli96f2a402017-06-05 17:24:2716520 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4716521 const HttpRequestInfo& info,
16522 RequestPriority priority,
16523 const SSLConfig& server_ssl_config,
16524 const SSLConfig& proxy_ssl_config,
16525 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4616526 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2916527 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616528 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016529 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2716530 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1916531 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4416532 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716533 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716534 }
16535
dchengb03027d2014-10-21 12:00:2016536 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5916537 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4716538 ADD_FAILURE();
16539 }
16540
dchengb03027d2014-10-21 12:00:2016541 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4716542 ADD_FAILURE();
16543 return NULL;
16544 }
16545
xunjielif5267de2017-01-20 21:18:5716546 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
16547 const std::string& parent_absolute_name) const override {
16548 ADD_FAILURE();
16549 }
16550
[email protected]bf828982013-08-14 18:01:4716551 private:
16552 base::WeakPtr<FakeStreamRequest> last_stream_request_;
16553
16554 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16555};
16556
[email protected]bf828982013-08-14 18:01:4716557} // namespace
16558
16559// Make sure that HttpNetworkTransaction passes on its priority to its
16560// stream request on start.
bncd16676a2016-07-20 16:23:0116561TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916562 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216563 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716564 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916565 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716566
krasinc06a72a2016-12-21 03:42:4616567 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116568 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716569
Ramin Halavatib5e433e2018-02-07 07:41:1016570 request.traffic_annotation =
16571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16572
wezca1070932016-05-26 20:30:5216573 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716574
[email protected]bf828982013-08-14 18:01:4716575 TestCompletionCallback callback;
16576 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016577 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716578
16579 base::WeakPtr<FakeStreamRequest> fake_request =
16580 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216581 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716582 EXPECT_EQ(LOW, fake_request->priority());
16583}
16584
16585// Make sure that HttpNetworkTransaction passes on its priority
16586// updates to its stream request.
bncd16676a2016-07-20 16:23:0116587TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216589 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716590 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916591 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716592
krasinc06a72a2016-12-21 03:42:4616593 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116594 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716595
Ramin Halavatib5e433e2018-02-07 07:41:1016596 request.traffic_annotation =
16597 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16598
[email protected]bf828982013-08-14 18:01:4716599 TestCompletionCallback callback;
16600 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016601 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716602
16603 base::WeakPtr<FakeStreamRequest> fake_request =
16604 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216605 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716606 EXPECT_EQ(LOW, fake_request->priority());
16607
16608 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216609 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716610 EXPECT_EQ(LOWEST, fake_request->priority());
16611}
16612
[email protected]e86839fd2013-08-14 18:29:0316613// Make sure that HttpNetworkTransaction passes on its priority
16614// updates to its stream.
bncd16676a2016-07-20 16:23:0116615TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216617 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316618 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916619 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316620
krasinc06a72a2016-12-21 03:42:4616621 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116622 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316623
Ramin Halavatib5e433e2018-02-07 07:41:1016624 request.traffic_annotation =
16625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16626
[email protected]e86839fd2013-08-14 18:29:0316627 TestCompletionCallback callback;
16628 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016629 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316630
16631 base::WeakPtr<FakeStreamRequest> fake_request =
16632 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216633 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316634 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216635 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316636 EXPECT_EQ(LOW, fake_stream->priority());
16637
16638 trans.SetPriority(LOWEST);
16639 EXPECT_EQ(LOWEST, fake_stream->priority());
16640}
16641
[email protected]043b68c82013-08-22 23:41:5216642// Tests that when a used socket is returned to the SSL socket pool, it's closed
16643// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116644TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216645 ClientSocketPoolManager::set_max_sockets_per_group(
16646 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16647 ClientSocketPoolManager::set_max_sockets_per_pool(
16648 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16649
16650 // Set up SSL request.
16651
16652 HttpRequestInfo ssl_request;
16653 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316654 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016655 ssl_request.traffic_annotation =
16656 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216657
16658 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316659 MockWrite(
16660 "GET / HTTP/1.1\r\n"
16661 "Host: www.example.org\r\n"
16662 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216663 };
16664 MockRead ssl_reads[] = {
16665 MockRead("HTTP/1.1 200 OK\r\n"),
16666 MockRead("Content-Length: 11\r\n\r\n"),
16667 MockRead("hello world"),
16668 MockRead(SYNCHRONOUS, OK),
16669 };
16670 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16671 ssl_writes, arraysize(ssl_writes));
16672 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16673
16674 SSLSocketDataProvider ssl(ASYNC, OK);
16675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16676
16677 // Set up HTTP request.
16678
16679 HttpRequestInfo http_request;
16680 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316681 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016682 http_request.traffic_annotation =
16683 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216684
16685 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316686 MockWrite(
16687 "GET / HTTP/1.1\r\n"
16688 "Host: www.example.org\r\n"
16689 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216690 };
16691 MockRead http_reads[] = {
16692 MockRead("HTTP/1.1 200 OK\r\n"),
16693 MockRead("Content-Length: 7\r\n\r\n"),
16694 MockRead("falafel"),
16695 MockRead(SYNCHRONOUS, OK),
16696 };
16697 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16698 http_writes, arraysize(http_writes));
16699 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16700
danakj1fd259a02016-04-16 03:17:0916701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216702
16703 // Start the SSL request.
16704 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616705 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016706 ASSERT_EQ(ERR_IO_PENDING,
16707 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16708 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216709
16710 // Start the HTTP request. Pool should stall.
16711 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616712 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016713 ASSERT_EQ(ERR_IO_PENDING,
16714 http_trans.Start(&http_request, http_callback.callback(),
16715 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116716 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216717
16718 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116719 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216720 std::string response_data;
bnc691fda62016-08-12 00:43:1616721 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216722 EXPECT_EQ("hello world", response_data);
16723
16724 // The SSL socket should automatically be closed, so the HTTP request can
16725 // start.
dcheng48459ac22014-08-26 00:46:4116726 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16727 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216728
16729 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116730 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616731 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216732 EXPECT_EQ("falafel", response_data);
16733
dcheng48459ac22014-08-26 00:46:4116734 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216735}
16736
16737// Tests that when a SSL connection is established but there's no corresponding
16738// request that needs it, the new socket is closed if the transport socket pool
16739// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116740TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216741 ClientSocketPoolManager::set_max_sockets_per_group(
16742 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16743 ClientSocketPoolManager::set_max_sockets_per_pool(
16744 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16745
16746 // Set up an ssl request.
16747
16748 HttpRequestInfo ssl_request;
16749 ssl_request.method = "GET";
16750 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1016751 ssl_request.traffic_annotation =
16752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216753
16754 // No data will be sent on the SSL socket.
16755 StaticSocketDataProvider ssl_data;
16756 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16757
16758 SSLSocketDataProvider ssl(ASYNC, OK);
16759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16760
16761 // Set up HTTP request.
16762
16763 HttpRequestInfo http_request;
16764 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316765 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016766 http_request.traffic_annotation =
16767 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216768
16769 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316770 MockWrite(
16771 "GET / HTTP/1.1\r\n"
16772 "Host: www.example.org\r\n"
16773 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216774 };
16775 MockRead http_reads[] = {
16776 MockRead("HTTP/1.1 200 OK\r\n"),
16777 MockRead("Content-Length: 7\r\n\r\n"),
16778 MockRead("falafel"),
16779 MockRead(SYNCHRONOUS, OK),
16780 };
16781 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16782 http_writes, arraysize(http_writes));
16783 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16784
danakj1fd259a02016-04-16 03:17:0916785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216786
16787 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16788 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916789 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916790 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116791 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216792
16793 // Start the HTTP request. Pool should stall.
16794 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616795 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016796 ASSERT_EQ(ERR_IO_PENDING,
16797 http_trans.Start(&http_request, http_callback.callback(),
16798 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116799 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216800
16801 // The SSL connection will automatically be closed once the connection is
16802 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116803 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216804 std::string response_data;
bnc691fda62016-08-12 00:43:1616805 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216806 EXPECT_EQ("falafel", response_data);
16807
dcheng48459ac22014-08-26 00:46:4116808 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216809}
16810
bncd16676a2016-07-20 16:23:0116811TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916812 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216813 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916814 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216815 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416816
16817 HttpRequestInfo request;
16818 request.method = "POST";
16819 request.url = GURL("http://www.foo.com/");
16820 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016821 request.traffic_annotation =
16822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416823
danakj1fd259a02016-04-16 03:17:0916824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616825 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416826 // Send headers successfully, but get an error while sending the body.
16827 MockWrite data_writes[] = {
16828 MockWrite("POST / HTTP/1.1\r\n"
16829 "Host: www.foo.com\r\n"
16830 "Connection: keep-alive\r\n"
16831 "Content-Length: 3\r\n\r\n"),
16832 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16833 };
16834
16835 MockRead data_reads[] = {
16836 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16837 MockRead("hello world"),
16838 MockRead(SYNCHRONOUS, OK),
16839 };
16840 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16841 arraysize(data_writes));
16842 session_deps_.socket_factory->AddSocketDataProvider(&data);
16843
16844 TestCompletionCallback callback;
16845
tfarina42834112016-09-22 13:38:2016846 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416848
16849 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116850 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416851
bnc691fda62016-08-12 00:43:1616852 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216853 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416854
wezca1070932016-05-26 20:30:5216855 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416856 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16857
16858 std::string response_data;
bnc691fda62016-08-12 00:43:1616859 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116860 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416861 EXPECT_EQ("hello world", response_data);
16862}
16863
16864// This test makes sure the retry logic doesn't trigger when reading an error
16865// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116866TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416867 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916868 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416869 MockWrite data_writes[] = {
16870 MockWrite("GET / HTTP/1.1\r\n"
16871 "Host: www.foo.com\r\n"
16872 "Connection: keep-alive\r\n\r\n"),
16873 MockWrite("POST / HTTP/1.1\r\n"
16874 "Host: www.foo.com\r\n"
16875 "Connection: keep-alive\r\n"
16876 "Content-Length: 3\r\n\r\n"),
16877 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16878 };
16879
16880 MockRead data_reads[] = {
16881 MockRead("HTTP/1.1 200 Peachy\r\n"
16882 "Content-Length: 14\r\n\r\n"),
16883 MockRead("first response"),
16884 MockRead("HTTP/1.1 400 Not OK\r\n"
16885 "Content-Length: 15\r\n\r\n"),
16886 MockRead("second response"),
16887 MockRead(SYNCHRONOUS, OK),
16888 };
16889 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16890 arraysize(data_writes));
16891 session_deps_.socket_factory->AddSocketDataProvider(&data);
16892
16893 TestCompletionCallback callback;
16894 HttpRequestInfo request1;
16895 request1.method = "GET";
16896 request1.url = GURL("http://www.foo.com/");
16897 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016898 request1.traffic_annotation =
16899 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416900
bnc87dcefc2017-05-25 12:47:5816901 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916902 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016903 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416905
16906 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116907 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416908
16909 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216910 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416911
wezca1070932016-05-26 20:30:5216912 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416913 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16914
16915 std::string response_data1;
16916 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116917 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416918 EXPECT_EQ("first response", response_data1);
16919 // Delete the transaction to release the socket back into the socket pool.
16920 trans1.reset();
16921
danakj1fd259a02016-04-16 03:17:0916922 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216923 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916924 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216925 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416926
16927 HttpRequestInfo request2;
16928 request2.method = "POST";
16929 request2.url = GURL("http://www.foo.com/");
16930 request2.upload_data_stream = &upload_data_stream;
16931 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016932 request2.traffic_annotation =
16933 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416934
bnc691fda62016-08-12 00:43:1616935 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016936 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416938
16939 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116940 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416941
bnc691fda62016-08-12 00:43:1616942 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216943 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416944
wezca1070932016-05-26 20:30:5216945 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416946 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16947
16948 std::string response_data2;
bnc691fda62016-08-12 00:43:1616949 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116950 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416951 EXPECT_EQ("second response", response_data2);
16952}
16953
bncd16676a2016-07-20 16:23:0116954TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416955 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916956 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216957 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916958 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216959 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416960
16961 HttpRequestInfo request;
16962 request.method = "POST";
16963 request.url = GURL("http://www.foo.com/");
16964 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016965 request.traffic_annotation =
16966 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416967
danakj1fd259a02016-04-16 03:17:0916968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416970 // Send headers successfully, but get an error while sending the body.
16971 MockWrite data_writes[] = {
16972 MockWrite("POST / HTTP/1.1\r\n"
16973 "Host: www.foo.com\r\n"
16974 "Connection: keep-alive\r\n"
16975 "Content-Length: 3\r\n\r\n"
16976 "fo"),
16977 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16978 };
16979
16980 MockRead data_reads[] = {
16981 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16982 MockRead("hello world"),
16983 MockRead(SYNCHRONOUS, OK),
16984 };
16985 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16986 arraysize(data_writes));
16987 session_deps_.socket_factory->AddSocketDataProvider(&data);
16988
16989 TestCompletionCallback callback;
16990
tfarina42834112016-09-22 13:38:2016991 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416993
16994 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116995 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416996
bnc691fda62016-08-12 00:43:1616997 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216998 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416999
wezca1070932016-05-26 20:30:5217000 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417001 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17002
17003 std::string response_data;
bnc691fda62016-08-12 00:43:1617004 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117005 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417006 EXPECT_EQ("hello world", response_data);
17007}
17008
17009// This tests the more common case than the previous test, where headers and
17010// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117011TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717012 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417013
17014 HttpRequestInfo request;
17015 request.method = "POST";
17016 request.url = GURL("http://www.foo.com/");
17017 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017018 request.traffic_annotation =
17019 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417020
danakj1fd259a02016-04-16 03:17:0917021 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617022 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417023 // Send headers successfully, but get an error while sending the body.
17024 MockWrite data_writes[] = {
17025 MockWrite("POST / HTTP/1.1\r\n"
17026 "Host: www.foo.com\r\n"
17027 "Connection: keep-alive\r\n"
17028 "Transfer-Encoding: chunked\r\n\r\n"),
17029 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17030 };
17031
17032 MockRead data_reads[] = {
17033 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17034 MockRead("hello world"),
17035 MockRead(SYNCHRONOUS, OK),
17036 };
17037 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17038 arraysize(data_writes));
17039 session_deps_.socket_factory->AddSocketDataProvider(&data);
17040
17041 TestCompletionCallback callback;
17042
tfarina42834112016-09-22 13:38:2017043 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417045 // Make sure the headers are sent before adding a chunk. This ensures that
17046 // they can't be merged with the body in a single send. Not currently
17047 // necessary since a chunked body is never merged with headers, but this makes
17048 // the test more future proof.
17049 base::RunLoop().RunUntilIdle();
17050
mmenkecbc2b712014-10-09 20:29:0717051 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417052
17053 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117054 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417055
bnc691fda62016-08-12 00:43:1617056 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217057 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417058
wezca1070932016-05-26 20:30:5217059 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417060 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17061
17062 std::string response_data;
bnc691fda62016-08-12 00:43:1617063 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117064 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417065 EXPECT_EQ("hello world", response_data);
17066}
17067
bncd16676a2016-07-20 16:23:0117068TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917069 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217070 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917071 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217072 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417073
17074 HttpRequestInfo request;
17075 request.method = "POST";
17076 request.url = GURL("http://www.foo.com/");
17077 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017078 request.traffic_annotation =
17079 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417080
danakj1fd259a02016-04-16 03:17:0917081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617082 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417083
17084 MockWrite data_writes[] = {
17085 MockWrite("POST / HTTP/1.1\r\n"
17086 "Host: www.foo.com\r\n"
17087 "Connection: keep-alive\r\n"
17088 "Content-Length: 3\r\n\r\n"),
17089 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17090 };
17091
17092 MockRead data_reads[] = {
17093 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17094 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17095 MockRead("hello world"),
17096 MockRead(SYNCHRONOUS, OK),
17097 };
17098 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17099 arraysize(data_writes));
17100 session_deps_.socket_factory->AddSocketDataProvider(&data);
17101
17102 TestCompletionCallback callback;
17103
tfarina42834112016-09-22 13:38:2017104 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417106
17107 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117108 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417109
bnc691fda62016-08-12 00:43:1617110 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217111 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417112
wezca1070932016-05-26 20:30:5217113 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417114 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17115
17116 std::string response_data;
bnc691fda62016-08-12 00:43:1617117 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117118 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417119 EXPECT_EQ("hello world", response_data);
17120}
17121
bncd16676a2016-07-20 16:23:0117122TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917123 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217124 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917125 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217126 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417127
17128 HttpRequestInfo request;
17129 request.method = "POST";
17130 request.url = GURL("http://www.foo.com/");
17131 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017132 request.traffic_annotation =
17133 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417134
danakj1fd259a02016-04-16 03:17:0917135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617136 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417137 // Send headers successfully, but get an error while sending the body.
17138 MockWrite data_writes[] = {
17139 MockWrite("POST / HTTP/1.1\r\n"
17140 "Host: www.foo.com\r\n"
17141 "Connection: keep-alive\r\n"
17142 "Content-Length: 3\r\n\r\n"),
17143 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17144 };
17145
17146 MockRead data_reads[] = {
17147 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17148 MockRead("hello world"),
17149 MockRead(SYNCHRONOUS, OK),
17150 };
17151 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17152 arraysize(data_writes));
17153 session_deps_.socket_factory->AddSocketDataProvider(&data);
17154
17155 TestCompletionCallback callback;
17156
tfarina42834112016-09-22 13:38:2017157 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417159
17160 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117161 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417162}
17163
bncd16676a2016-07-20 16:23:0117164TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417165 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917166 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217167 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917168 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217169 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417170
17171 HttpRequestInfo request;
17172 request.method = "POST";
17173 request.url = GURL("http://www.foo.com/");
17174 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017175 request.traffic_annotation =
17176 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417177
danakj1fd259a02016-04-16 03:17:0917178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617179 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417180 // Send headers successfully, but get an error while sending the body.
17181 MockWrite data_writes[] = {
17182 MockWrite("POST / HTTP/1.1\r\n"
17183 "Host: www.foo.com\r\n"
17184 "Connection: keep-alive\r\n"
17185 "Content-Length: 3\r\n\r\n"),
17186 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17187 };
17188
17189 MockRead data_reads[] = {
17190 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17191 MockRead("HTTP/1.0 302 Redirect\r\n"),
17192 MockRead("Location: http://somewhere-else.com/\r\n"),
17193 MockRead("Content-Length: 0\r\n\r\n"),
17194 MockRead(SYNCHRONOUS, OK),
17195 };
17196 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17197 arraysize(data_writes));
17198 session_deps_.socket_factory->AddSocketDataProvider(&data);
17199
17200 TestCompletionCallback callback;
17201
tfarina42834112016-09-22 13:38:2017202 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417204
17205 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117206 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417207}
17208
bncd16676a2016-07-20 16:23:0117209TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917210 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217211 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917212 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217213 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417214
17215 HttpRequestInfo request;
17216 request.method = "POST";
17217 request.url = GURL("http://www.foo.com/");
17218 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017219 request.traffic_annotation =
17220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417221
danakj1fd259a02016-04-16 03:17:0917222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417224 // Send headers successfully, but get an error while sending the body.
17225 MockWrite data_writes[] = {
17226 MockWrite("POST / HTTP/1.1\r\n"
17227 "Host: www.foo.com\r\n"
17228 "Connection: keep-alive\r\n"
17229 "Content-Length: 3\r\n\r\n"),
17230 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17231 };
17232
17233 MockRead data_reads[] = {
17234 MockRead("HTTP 0.9 rocks!"),
17235 MockRead(SYNCHRONOUS, OK),
17236 };
17237 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17238 arraysize(data_writes));
17239 session_deps_.socket_factory->AddSocketDataProvider(&data);
17240
17241 TestCompletionCallback callback;
17242
tfarina42834112016-09-22 13:38:2017243 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417245
17246 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117247 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417248}
17249
bncd16676a2016-07-20 16:23:0117250TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917251 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217252 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917253 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217254 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417255
17256 HttpRequestInfo request;
17257 request.method = "POST";
17258 request.url = GURL("http://www.foo.com/");
17259 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017260 request.traffic_annotation =
17261 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417262
danakj1fd259a02016-04-16 03:17:0917263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617264 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417265 // Send headers successfully, but get an error while sending the body.
17266 MockWrite data_writes[] = {
17267 MockWrite("POST / HTTP/1.1\r\n"
17268 "Host: www.foo.com\r\n"
17269 "Connection: keep-alive\r\n"
17270 "Content-Length: 3\r\n\r\n"),
17271 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17272 };
17273
17274 MockRead data_reads[] = {
17275 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17276 MockRead(SYNCHRONOUS, OK),
17277 };
17278 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17279 arraysize(data_writes));
17280 session_deps_.socket_factory->AddSocketDataProvider(&data);
17281
17282 TestCompletionCallback callback;
17283
tfarina42834112016-09-22 13:38:2017284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417286
17287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117288 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417289}
17290
Bence Békydca6bd92018-01-30 13:43:0617291#if BUILDFLAG(ENABLE_WEBSOCKETS)
17292
17293namespace {
17294
17295void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17296 headers->SetHeader("Connection", "Upgrade");
17297 headers->SetHeader("Upgrade", "websocket");
17298 headers->SetHeader("Origin", "http://www.example.org");
17299 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617300}
17301
17302} // namespace
17303
17304TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Békydca6bd92018-01-30 13:43:0617305 std::string test_cases[] = {"ws://www.example.org/",
17306 "wss://www.example.org/"};
17307 for (size_t i = 0; i < arraysize(test_cases); ++i) {
17308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17309 HttpNetworkSessionPeer peer(session.get());
17310 FakeStreamFactory* fake_factory = new FakeStreamFactory();
17311 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
17312
17313 HttpRequestInfo request;
17314 request.method = "GET";
17315 request.url = GURL(test_cases[i]);
Ramin Halavatib5e433e2018-02-07 07:41:1017316 request.traffic_annotation =
17317 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617318
Bence Béky8d1c6052018-02-07 12:48:1517319 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17320
Bence Békydca6bd92018-01-30 13:43:0617321 HttpNetworkTransaction trans(LOW, session.get());
17322 trans.SetWebSocketHandshakeStreamCreateHelper(
17323 &websocket_stream_create_helper);
17324
17325 TestCompletionCallback callback;
17326 EXPECT_EQ(ERR_IO_PENDING,
17327 trans.Start(&request, callback.callback(), NetLogWithSource()));
17328
17329 base::WeakPtr<FakeStreamRequest> fake_request =
17330 fake_factory->last_stream_request();
17331 ASSERT_TRUE(fake_request);
17332 EXPECT_EQ(&websocket_stream_create_helper,
17333 fake_request->websocket_stream_create_helper());
17334 }
17335}
17336
Adam Rice425cf122015-01-19 06:18:2417337// Verify that proxy headers are not sent to the destination server when
17338// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117339TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417340 HttpRequestInfo request;
17341 request.method = "GET";
bncce36dca22015-04-21 22:11:2317342 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017343 request.traffic_annotation =
17344 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417345 AddWebSocketHeaders(&request.extra_headers);
17346
17347 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917348 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917349 ProxyResolutionService::CreateFixedFromPacResult(
17350 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417351
danakj1fd259a02016-04-16 03:17:0917352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417353
17354 // Since a proxy is configured, try to establish a tunnel.
17355 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717356 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17357 "Host: www.example.org:443\r\n"
17358 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417359
17360 // After calling trans->RestartWithAuth(), this is the request we should
17361 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717362 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17363 "Host: www.example.org:443\r\n"
17364 "Proxy-Connection: keep-alive\r\n"
17365 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417366
rsleevidb16bb02015-11-12 23:47:1717367 MockWrite("GET / HTTP/1.1\r\n"
17368 "Host: www.example.org\r\n"
17369 "Connection: Upgrade\r\n"
17370 "Upgrade: websocket\r\n"
17371 "Origin: http://www.example.org\r\n"
17372 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517373 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17374 "Sec-WebSocket-Extensions: permessage-deflate; "
17375 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417376
17377 // The proxy responds to the connect with a 407, using a persistent
17378 // connection.
17379 MockRead data_reads[] = {
17380 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517381 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17382 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17383 "Content-Length: 0\r\n"
17384 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417385
17386 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17387
Bence Béky8d1c6052018-02-07 12:48:1517388 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17389 "Upgrade: websocket\r\n"
17390 "Connection: Upgrade\r\n"
17391 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417392
17393 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17394 arraysize(data_writes));
17395 session_deps_.socket_factory->AddSocketDataProvider(&data);
17396 SSLSocketDataProvider ssl(ASYNC, OK);
17397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17398
Bence Béky8d1c6052018-02-07 12:48:1517399 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17400
bnc87dcefc2017-05-25 12:47:5817401 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917402 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417403 trans->SetWebSocketHandshakeStreamCreateHelper(
17404 &websocket_stream_create_helper);
17405
17406 {
17407 TestCompletionCallback callback;
17408
tfarina42834112016-09-22 13:38:2017409 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417411
17412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117413 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417414 }
17415
17416 const HttpResponseInfo* response = trans->GetResponseInfo();
17417 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217418 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417419 EXPECT_EQ(407, response->headers->response_code());
17420
17421 {
17422 TestCompletionCallback callback;
17423
17424 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17425 callback.callback());
robpercival214763f2016-07-01 23:27:0117426 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417427
17428 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117429 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417430 }
17431
17432 response = trans->GetResponseInfo();
17433 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217434 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417435
17436 EXPECT_EQ(101, response->headers->response_code());
17437
17438 trans.reset();
17439 session->CloseAllConnections();
17440}
17441
17442// Verify that proxy headers are not sent to the destination server when
17443// establishing a tunnel for an insecure WebSocket connection.
17444// This requires the authentication info to be injected into the auth cache
17445// due to crbug.com/395064
17446// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117447TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417448 HttpRequestInfo request;
17449 request.method = "GET";
bncce36dca22015-04-21 22:11:2317450 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017451 request.traffic_annotation =
17452 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417453 AddWebSocketHeaders(&request.extra_headers);
17454
17455 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917456 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917457 ProxyResolutionService::CreateFixedFromPacResult(
17458 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417459
danakj1fd259a02016-04-16 03:17:0917460 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417461
17462 MockWrite data_writes[] = {
17463 // Try to establish a tunnel for the WebSocket connection, with
17464 // credentials. Because WebSockets have a separate set of socket pools,
17465 // they cannot and will not use the same TCP/IP connection as the
17466 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517467 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17468 "Host: www.example.org:80\r\n"
17469 "Proxy-Connection: keep-alive\r\n"
17470 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417471
Bence Béky8d1c6052018-02-07 12:48:1517472 MockWrite("GET / HTTP/1.1\r\n"
17473 "Host: www.example.org\r\n"
17474 "Connection: Upgrade\r\n"
17475 "Upgrade: websocket\r\n"
17476 "Origin: http://www.example.org\r\n"
17477 "Sec-WebSocket-Version: 13\r\n"
17478 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17479 "Sec-WebSocket-Extensions: permessage-deflate; "
17480 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417481
17482 MockRead data_reads[] = {
17483 // HTTP CONNECT with credentials.
17484 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17485
17486 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517487 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17488 "Upgrade: websocket\r\n"
17489 "Connection: Upgrade\r\n"
17490 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417491
17492 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17493 arraysize(data_writes));
17494 session_deps_.socket_factory->AddSocketDataProvider(&data);
17495
17496 session->http_auth_cache()->Add(
17497 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17498 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17499
Bence Béky8d1c6052018-02-07 12:48:1517500 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17501
bnc87dcefc2017-05-25 12:47:5817502 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917503 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417504 trans->SetWebSocketHandshakeStreamCreateHelper(
17505 &websocket_stream_create_helper);
17506
17507 TestCompletionCallback callback;
17508
tfarina42834112016-09-22 13:38:2017509 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417511
17512 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117513 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417514
17515 const HttpResponseInfo* response = trans->GetResponseInfo();
17516 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217517 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417518
17519 EXPECT_EQ(101, response->headers->response_code());
17520
17521 trans.reset();
17522 session->CloseAllConnections();
17523}
17524
Bence Békydca6bd92018-01-30 13:43:0617525#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17526
bncd16676a2016-07-20 16:23:0117527TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917528 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217529 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917530 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217531 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217532
17533 HttpRequestInfo request;
17534 request.method = "POST";
17535 request.url = GURL("http://www.foo.com/");
17536 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017537 request.traffic_annotation =
17538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217539
danakj1fd259a02016-04-16 03:17:0917540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217542 MockWrite data_writes[] = {
17543 MockWrite("POST / HTTP/1.1\r\n"
17544 "Host: www.foo.com\r\n"
17545 "Connection: keep-alive\r\n"
17546 "Content-Length: 3\r\n\r\n"),
17547 MockWrite("foo"),
17548 };
17549
17550 MockRead data_reads[] = {
17551 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17552 MockRead(SYNCHRONOUS, OK),
17553 };
17554 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17555 arraysize(data_writes));
17556 session_deps_.socket_factory->AddSocketDataProvider(&data);
17557
17558 TestCompletionCallback callback;
17559
17560 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017561 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117562 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217563
17564 std::string response_data;
bnc691fda62016-08-12 00:43:1617565 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217566
17567 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617568 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217569 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617570 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217571}
17572
bncd16676a2016-07-20 16:23:0117573TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917574 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217575 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917576 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217577 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217578
17579 HttpRequestInfo request;
17580 request.method = "POST";
17581 request.url = GURL("http://www.foo.com/");
17582 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017583 request.traffic_annotation =
17584 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217585
danakj1fd259a02016-04-16 03:17:0917586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217588 MockWrite data_writes[] = {
17589 MockWrite("POST / HTTP/1.1\r\n"
17590 "Host: www.foo.com\r\n"
17591 "Connection: keep-alive\r\n"
17592 "Content-Length: 3\r\n\r\n"),
17593 MockWrite("foo"),
17594 };
17595
17596 MockRead data_reads[] = {
17597 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17598 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17599 MockRead(SYNCHRONOUS, OK),
17600 };
17601 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17602 arraysize(data_writes));
17603 session_deps_.socket_factory->AddSocketDataProvider(&data);
17604
17605 TestCompletionCallback callback;
17606
17607 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017608 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117609 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217610
17611 std::string response_data;
bnc691fda62016-08-12 00:43:1617612 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217613
17614 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617615 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217616 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617617 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217618}
17619
bncd16676a2016-07-20 16:23:0117620TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217621 ChunkedUploadDataStream upload_data_stream(0);
17622
17623 HttpRequestInfo request;
17624 request.method = "POST";
17625 request.url = GURL("http://www.foo.com/");
17626 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017627 request.traffic_annotation =
17628 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217629
danakj1fd259a02016-04-16 03:17:0917630 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217632 // Send headers successfully, but get an error while sending the body.
17633 MockWrite data_writes[] = {
17634 MockWrite("POST / HTTP/1.1\r\n"
17635 "Host: www.foo.com\r\n"
17636 "Connection: keep-alive\r\n"
17637 "Transfer-Encoding: chunked\r\n\r\n"),
17638 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17639 };
17640
17641 MockRead data_reads[] = {
17642 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17643 MockRead(SYNCHRONOUS, OK),
17644 };
17645 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17646 arraysize(data_writes));
17647 session_deps_.socket_factory->AddSocketDataProvider(&data);
17648
17649 TestCompletionCallback callback;
17650
17651 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017652 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217653
17654 base::RunLoop().RunUntilIdle();
17655 upload_data_stream.AppendData("f", 1, false);
17656
17657 base::RunLoop().RunUntilIdle();
17658 upload_data_stream.AppendData("oo", 2, true);
17659
robpercival214763f2016-07-01 23:27:0117660 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217661
17662 std::string response_data;
bnc691fda62016-08-12 00:43:1617663 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217664
17665 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617666 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217667 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617668 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217669}
17670
nharperb7441ef2016-01-25 23:54:1417671#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117672TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417673 const std::string https_url = "https://www.example.com";
17674 HttpRequestInfo request;
17675 request.url = GURL(https_url);
17676 request.method = "GET";
Ramin Halavatib5e433e2018-02-07 07:41:1017677 request.traffic_annotation =
17678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417679
17680 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917681 ssl.ssl_info.token_binding_negotiated = true;
17682 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617683 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17685
bnc42331402016-07-25 13:36:1517686 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117687 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17688 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417689 MockRead(ASYNC, ERR_IO_PENDING)};
17690 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17691 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817692 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917693 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417695
17696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17697 TestCompletionCallback callback;
17698 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017699 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017700
17701 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417702
17703 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17704 HttpRequestHeaders headers;
17705 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17706 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17707}
17708#endif // !defined(OS_IOS)
17709
eustasc7d27da2017-04-06 10:33:2017710void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17711 const std::string& accept_encoding,
17712 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317713 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017714 bool should_match) {
17715 HttpRequestInfo request;
17716 request.method = "GET";
17717 request.url = GURL("http://www.foo.com/");
17718 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17719 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017720 request.traffic_annotation =
17721 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017722
17723 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17725 // Send headers successfully, but get an error while sending the body.
17726 MockWrite data_writes[] = {
17727 MockWrite("GET / HTTP/1.1\r\n"
17728 "Host: www.foo.com\r\n"
17729 "Connection: keep-alive\r\n"
17730 "Accept-Encoding: "),
17731 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17732 };
17733
sky50576f32017-05-01 19:28:0317734 std::string response_code = "200 OK";
17735 std::string extra;
17736 if (!location.empty()) {
17737 response_code = "301 Redirect\r\nLocation: ";
17738 response_code.append(location);
17739 }
17740
eustasc7d27da2017-04-06 10:33:2017741 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317742 MockRead("HTTP/1.0 "),
17743 MockRead(response_code.data()),
17744 MockRead("\r\nContent-Encoding: "),
17745 MockRead(content_encoding.data()),
17746 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017747 MockRead(SYNCHRONOUS, OK),
17748 };
17749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17750 arraysize(data_writes));
17751 session_deps->socket_factory->AddSocketDataProvider(&data);
17752
17753 TestCompletionCallback callback;
17754
17755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17757
17758 rv = callback.WaitForResult();
17759 if (should_match) {
17760 EXPECT_THAT(rv, IsOk());
17761 } else {
17762 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17763 }
17764}
17765
17766TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317767 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017768}
17769
17770TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317771 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17772 true);
eustasc7d27da2017-04-06 10:33:2017773}
17774
17775TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17776 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317777 "", false);
17778}
17779
17780TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17781 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17782 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017783}
17784
xunjieli96f2a402017-06-05 17:24:2717785TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17786 ProxyConfig proxy_config;
17787 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17788 proxy_config.set_pac_mandatory(true);
17789 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917790 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917791 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17792 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0417793 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717794
17795 HttpRequestInfo request;
17796 request.method = "GET";
17797 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017798 request.traffic_annotation =
17799 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717800
17801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17803
17804 TestCompletionCallback callback;
17805
17806 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17808 EXPECT_THAT(callback.WaitForResult(),
17809 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17810}
17811
17812TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17813 ProxyConfig proxy_config;
17814 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17815 proxy_config.set_pac_mandatory(true);
17816 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17817 new MockAsyncProxyResolverFactory(false);
17818 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917819 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917820 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17821 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5917822 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717823 HttpRequestInfo request;
17824 request.method = "GET";
17825 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017826 request.traffic_annotation =
17827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717828
17829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17831
17832 TestCompletionCallback callback;
17833 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17835
17836 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17837 ERR_FAILED, &resolver);
17838 EXPECT_THAT(callback.WaitForResult(),
17839 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17840}
17841
17842TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917843 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917844 ProxyResolutionService::CreateFixedFromPacResult(
17845 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717846 session_deps_.enable_quic = false;
17847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17848
17849 HttpRequestInfo request;
17850 request.method = "GET";
17851 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017852 request.traffic_annotation =
17853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717854
17855 TestCompletionCallback callback;
17856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17857 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17859
17860 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17861}
17862
[email protected]89ceba9a2009-03-21 03:46:0617863} // namespace net