blob: 69d3c2fd13604dc40c5a4027ccf82532db7087ad [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"
rdsmith1d343be52016-10-21 20:37:5040#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1541#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3143#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5244#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1545#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0646#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2147#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0848#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1149#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1650#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5351#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2452#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1253#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0054#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2955#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1956#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5757#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5258#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5659#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2460#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1361#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5362#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5763#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3864#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1965#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0766#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0067#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1968#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5169#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4670#include "net/log/test_net_log_entry.h"
71#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4072#include "net/proxy_resolution/mock_proxy_resolver.h"
73#include "net/proxy_resolution/proxy_config_service_fixed.h"
74#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0375#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4076#include "net/proxy_resolution/proxy_resolver.h"
77#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1579#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0380#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4781#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0282#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0783#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0484#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4485#include "net/socket/socket_test_util.h"
86#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0687#include "net/spdy/chromium/spdy_session.h"
88#include "net/spdy/chromium/spdy_session_pool.h"
89#include "net/spdy/chromium/spdy_test_util_common.h"
90#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1491#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5792#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0393#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5794#include "net/ssl/ssl_config_service_defaults.h"
95#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5496#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1197#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0198#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1099#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:43100#include "net/test/test_data_directory.h"
[email protected]baee31a2018-01-18 06:10:23101#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44102#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06103#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18104#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52105#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15106#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27107#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52108
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37109#if defined(NTLM_PORTABLE)
110#include "base/base64.h"
111#include "net/ntlm/ntlm_test_data.h"
112#endif
113
robpercival214763f2016-07-01 23:27:01114using net::test::IsError;
115using net::test::IsOk;
116
[email protected]ad65a3e2013-12-25 18:18:01117using base::ASCIIToUTF16;
118
initial.commit586acc5fe2008-07-26 22:42:52119//-----------------------------------------------------------------------------
120
ttuttle859dc7a2015-04-23 19:42:29121namespace net {
122
[email protected]13c8a092010-07-29 06:15:44123namespace {
124
rdsmith1d343be52016-10-21 20:37:50125class TestNetworkStreamThrottler : public NetworkThrottleManager {
126 public:
127 TestNetworkStreamThrottler()
128 : throttle_new_requests_(false),
129 num_set_priority_calls_(0),
130 last_priority_set_(IDLE) {}
131
132 ~TestNetworkStreamThrottler() override {
133 EXPECT_TRUE(outstanding_throttles_.empty());
134 }
135
136 // NetworkThrottleManager
137 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
138 RequestPriority priority,
139 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58140 auto test_throttle =
Jeremy Roman0579ed62017-08-29 15:56:19141 std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50142 outstanding_throttles_.insert(test_throttle.get());
143 return std::move(test_throttle);
144 }
145
146 void UnthrottleAllRequests() {
147 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25148 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24149 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50150 throttle->Unthrottle();
151 }
152 }
153
154 void set_throttle_new_requests(bool throttle_new_requests) {
155 throttle_new_requests_ = throttle_new_requests;
156 }
157
158 // Includes both throttled and unthrottled throttles.
159 size_t num_outstanding_requests() const {
160 return outstanding_throttles_.size();
161 }
162
163 int num_set_priority_calls() const { return num_set_priority_calls_; }
164 RequestPriority last_priority_set() const { return last_priority_set_; }
165 void set_priority_change_closure(
166 const base::Closure& priority_change_closure) {
167 priority_change_closure_ = priority_change_closure;
168 }
169
170 private:
171 class TestThrottle : public NetworkThrottleManager::Throttle {
172 public:
173 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
174
175 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24176 bool IsBlocked() const override { return throttled_; }
177 RequestPriority Priority() const override {
178 NOTREACHED();
179 return IDLE;
180 }
rdsmith1d343be52016-10-21 20:37:50181 void SetPriority(RequestPriority priority) override {
182 throttler_->SetPriorityCalled(priority);
183 }
184
185 TestThrottle(bool throttled,
186 ThrottleDelegate* delegate,
187 TestNetworkStreamThrottler* throttler)
188 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
189
190 void Unthrottle() {
191 EXPECT_TRUE(throttled_);
192
193 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24194 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50195 }
196
197 bool throttled_;
198 ThrottleDelegate* delegate_;
199 TestNetworkStreamThrottler* throttler_;
200 };
201
202 void OnThrottleDestroyed(TestThrottle* throttle) {
203 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
204 outstanding_throttles_.erase(throttle);
205 }
206
207 void SetPriorityCalled(RequestPriority priority) {
208 ++num_set_priority_calls_;
209 last_priority_set_ = priority;
210 if (!priority_change_closure_.is_null())
211 priority_change_closure_.Run();
212 }
213
214 // Includes both throttled and unthrottled throttles.
215 std::set<TestThrottle*> outstanding_throttles_;
216 bool throttle_new_requests_;
217 int num_set_priority_calls_;
218 RequestPriority last_priority_set_;
219 base::Closure priority_change_closure_;
220
221 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
222};
223
[email protected]42cba2fb2013-03-29 19:58:57224const base::string16 kBar(ASCIIToUTF16("bar"));
225const base::string16 kBar2(ASCIIToUTF16("bar2"));
226const base::string16 kBar3(ASCIIToUTF16("bar3"));
227const base::string16 kBaz(ASCIIToUTF16("baz"));
228const base::string16 kFirst(ASCIIToUTF16("first"));
229const base::string16 kFoo(ASCIIToUTF16("foo"));
230const base::string16 kFoo2(ASCIIToUTF16("foo2"));
231const base::string16 kFoo3(ASCIIToUTF16("foo3"));
232const base::string16 kFou(ASCIIToUTF16("fou"));
233const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57234const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44235
bnc2df4b522016-07-08 18:17:43236const char kAlternativeServiceHttpHeader[] =
237 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
238
ttuttle859dc7a2015-04-23 19:42:29239int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
240 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
241 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02242}
243
ttuttle859dc7a2015-04-23 19:42:29244int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
245 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
246 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02247}
248
ttuttle859dc7a2015-04-23 19:42:29249bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
250 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
251 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52252}
253
[email protected]f3da152d2012-06-02 01:00:57254// Takes in a Value created from a NetLogHttpResponseParameter, and returns
255// a JSONified list of headers as a single string. Uses single quotes instead
256// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27257bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57258 if (!params)
259 return false;
[email protected]ea5ef4c2013-06-13 22:50:27260 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57261 if (!params->GetList("headers", &header_list))
262 return false;
263 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34264 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28265 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57266 return true;
267}
268
[email protected]029c83b62013-01-24 05:28:20269// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
270// used.
ttuttle859dc7a2015-04-23 19:42:29271void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20272 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19273 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25274
[email protected]029c83b62013-01-24 05:28:20275 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
276 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
277
ttuttle859dc7a2015-04-23 19:42:29278 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20279 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25280
281 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25282
[email protected]3b23a222013-05-15 21:33:25283 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25284 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
285 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25286 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25287}
288
[email protected]029c83b62013-01-24 05:28:20289// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
290// used.
ttuttle859dc7a2015-04-23 19:42:29291void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25292 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20293 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19294 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20295
296 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
297 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
298
ttuttle859dc7a2015-04-23 19:42:29299 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
300 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20301 EXPECT_LE(load_timing_info.connect_timing.connect_end,
302 load_timing_info.send_start);
303
304 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20305
[email protected]3b23a222013-05-15 21:33:25306 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20307 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
308 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25309 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20310}
311
312// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
313// used.
ttuttle859dc7a2015-04-23 19:42:29314void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20315 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19316 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20317
ttuttle859dc7a2015-04-23 19:42:29318 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20319
320 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
321 EXPECT_LE(load_timing_info.proxy_resolve_start,
322 load_timing_info.proxy_resolve_end);
323 EXPECT_LE(load_timing_info.proxy_resolve_end,
324 load_timing_info.send_start);
325 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20326
[email protected]3b23a222013-05-15 21:33:25327 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20328 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
329 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25330 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20331}
332
333// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
334// used.
ttuttle859dc7a2015-04-23 19:42:29335void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20336 int connect_timing_flags) {
337 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19338 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20339
340 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
341 EXPECT_LE(load_timing_info.proxy_resolve_start,
342 load_timing_info.proxy_resolve_end);
343 EXPECT_LE(load_timing_info.proxy_resolve_end,
344 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29345 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
346 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20347 EXPECT_LE(load_timing_info.connect_timing.connect_end,
348 load_timing_info.send_start);
349
350 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20351
[email protected]3b23a222013-05-15 21:33:25352 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20353 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
354 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25355 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25356}
357
danakj1fd259a02016-04-16 03:17:09358std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42359 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34360 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14361}
362
rdsmith1d343be52016-10-21 20:37:50363// Note that the pointer written into |*throttler| will only be valid
364// for the lifetime of the returned HttpNetworkSession.
365std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
366 SpdySessionDependencies* session_deps,
367 TestNetworkStreamThrottler** throttler) {
368 std::unique_ptr<HttpNetworkSession> session(
369 SpdySessionDependencies::SpdyCreateSession(session_deps));
370
Jeremy Roman0579ed62017-08-29 15:56:19371 auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50372 *throttler = owned_throttler.get();
373
374 HttpNetworkSessionPeer peer(session.get());
375 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
376
377 return session;
378}
379
xunjieli96f2a402017-06-05 17:24:27380class FailingProxyResolverFactory : public ProxyResolverFactory {
381 public:
382 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
383
384 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42385 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
386 std::unique_ptr<ProxyResolver>* result,
387 const CompletionCallback& callback,
388 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27389 return ERR_PAC_SCRIPT_FAILED;
390 }
391};
392
[email protected]448d4ca52012-03-04 04:12:23393} // namespace
394
bncd16676a2016-07-20 16:23:01395class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03396 public:
bncd16676a2016-07-20 16:23:01397 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03398 // Important to restore the per-pool limit first, since the pool limit must
399 // always be greater than group limit, and the tests reduce both limits.
400 ClientSocketPoolManager::set_max_sockets_per_pool(
401 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
402 ClientSocketPoolManager::set_max_sockets_per_group(
403 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
404 }
405
[email protected]e3ceb682011-06-28 23:55:46406 protected:
[email protected]23e482282013-06-14 16:08:02407 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15408 : ssl_(ASYNC, OK),
409 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03410 HttpNetworkSession::NORMAL_SOCKET_POOL)),
411 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
412 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28413 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03414 }
[email protected]bb88e1d32013-05-03 23:11:07415
[email protected]e3ceb682011-06-28 23:55:46416 struct SimpleGetHelperResult {
417 int rv;
418 std::string status_line;
419 std::string response_data;
sclittlefb249892015-09-10 21:33:22420 int64_t total_received_bytes;
421 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25422 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47423 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59424 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46425 };
426
dcheng67be2b1f2014-10-27 21:47:29427 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50428 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55429 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54430 }
431
dcheng67be2b1f2014-10-27 21:47:29432 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50433 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55434 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09435 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55436 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09437 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50438 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55439 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09440 }
441
[email protected]202965992011-12-07 23:04:51442 // Either |write_failure| specifies a write failure or |read_failure|
443 // specifies a read failure when using a reused socket. In either case, the
444 // failure should cause the network transaction to resend the request, and the
445 // other argument should be NULL.
446 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
447 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52448
[email protected]a34f61ee2014-03-18 20:59:49449 // Either |write_failure| specifies a write failure or |read_failure|
450 // specifies a read failure when using a reused socket. In either case, the
451 // failure should cause the network transaction to resend the request, and the
452 // other argument should be NULL.
453 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10454 const MockRead* read_failure,
455 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49456
[email protected]5a60c8b2011-10-19 20:14:29457 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
458 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15459 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52460
[email protected]ff007e162009-05-23 09:13:15461 HttpRequestInfo request;
462 request.method = "GET";
bncce36dca22015-04-21 22:11:23463 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10464 request.traffic_annotation =
465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52466
vishal.b62985ca92015-04-17 08:45:51467 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07468 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27471
[email protected]5a60c8b2011-10-19 20:14:29472 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07473 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29474 }
initial.commit586acc5fe2008-07-26 22:42:52475
[email protected]49639fa2011-12-20 23:22:41476 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52477
eroman24bc6a12015-05-06 19:55:48478 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16479 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52481
[email protected]ff007e162009-05-23 09:13:15482 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16483 out.total_received_bytes = trans.GetTotalReceivedBytes();
484 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25485
486 // Even in the failure cases that use this function, connections are always
487 // successfully established before the error.
bnc691fda62016-08-12 00:43:16488 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25489 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
490
[email protected]ff007e162009-05-23 09:13:15491 if (out.rv != OK)
492 return out;
493
bnc691fda62016-08-12 00:43:16494 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50495 // Can't use ASSERT_* inside helper functions like this, so
496 // return an error.
wezca1070932016-05-26 20:30:52497 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50498 out.rv = ERR_UNEXPECTED;
499 return out;
500 }
[email protected]ff007e162009-05-23 09:13:15501 out.status_line = response->headers->GetStatusLine();
502
[email protected]80a09a82012-11-16 17:40:06503 EXPECT_EQ("127.0.0.1", response->socket_address.host());
504 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19505
ttuttled9dbc652015-09-29 20:00:59506 bool got_endpoint =
bnc691fda62016-08-12 00:43:16507 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59508 EXPECT_EQ(got_endpoint,
509 out.remote_endpoint_after_start.address().size() > 0);
510
bnc691fda62016-08-12 00:43:16511 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01512 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40513
mmenke43758e62015-05-04 21:09:46514 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40515 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39516 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00517 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
518 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39519 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00520 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
521 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15522
[email protected]f3da152d2012-06-02 01:00:57523 std::string line;
524 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
525 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
526
[email protected]79e1fd62013-06-20 06:50:04527 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16528 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04529 std::string value;
530 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23531 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04532 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
533 EXPECT_EQ("keep-alive", value);
534
535 std::string response_headers;
536 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23537 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04538 response_headers);
[email protected]3deb9a52010-11-11 00:24:40539
bnc691fda62016-08-12 00:43:16540 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22541 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16542 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22543
bnc691fda62016-08-12 00:43:16544 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47545 return out;
[email protected]ff007e162009-05-23 09:13:15546 }
initial.commit586acc5fe2008-07-26 22:42:52547
[email protected]5a60c8b2011-10-19 20:14:29548 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
549 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22550 MockWrite data_writes[] = {
551 MockWrite("GET / HTTP/1.1\r\n"
552 "Host: www.example.org\r\n"
553 "Connection: keep-alive\r\n\r\n"),
554 };
[email protected]5a60c8b2011-10-19 20:14:29555
sclittlefb249892015-09-10 21:33:22556 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
557 arraysize(data_writes));
558 StaticSocketDataProvider* data[] = {&reads};
559 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
560
561 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
562 out.total_sent_bytes);
563 return out;
[email protected]b8015c42013-12-24 15:18:19564 }
565
bnc032658ba2016-09-26 18:17:15566 void AddSSLSocketData() {
567 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49568 ssl_.ssl_info.cert =
569 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
570 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
572 }
573
[email protected]ff007e162009-05-23 09:13:15574 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
575 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52576
[email protected]ff007e162009-05-23 09:13:15577 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07578
579 void BypassHostCacheOnRefreshHelper(int load_flags);
580
581 void CheckErrorIsPassedBack(int error, IoMode mode);
582
[email protected]4bd46222013-05-14 19:32:23583 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07584 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15585 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03586
587 // Original socket limits. Some tests set these. Safest to always restore
588 // them once each test has been run.
589 int old_max_group_sockets_;
590 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15591};
[email protected]231d5a32008-09-13 00:45:27592
[email protected]448d4ca52012-03-04 04:12:23593namespace {
594
ryansturm49a8cb12016-06-15 16:51:09595class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27596 public:
ryansturm49a8cb12016-06-15 16:51:09597 BeforeHeadersSentHandler()
598 : observed_before_headers_sent_with_proxy_(false),
599 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27600
ryansturm49a8cb12016-06-15 16:51:09601 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
602 HttpRequestHeaders* request_headers) {
603 observed_before_headers_sent_ = true;
604 if (!proxy_info.is_http() && !proxy_info.is_https() &&
605 !proxy_info.is_quic()) {
606 return;
607 }
608 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27609 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
610 }
611
ryansturm49a8cb12016-06-15 16:51:09612 bool observed_before_headers_sent_with_proxy() const {
613 return observed_before_headers_sent_with_proxy_;
614 }
615
616 bool observed_before_headers_sent() const {
617 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27618 }
619
620 std::string observed_proxy_server_uri() const {
621 return observed_proxy_server_uri_;
622 }
623
624 private:
ryansturm49a8cb12016-06-15 16:51:09625 bool observed_before_headers_sent_with_proxy_;
626 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27627 std::string observed_proxy_server_uri_;
628
ryansturm49a8cb12016-06-15 16:51:09629 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27630};
631
[email protected]15a5ccf82008-10-23 19:57:43632// Fill |str| with a long header list that consumes >= |size| bytes.
633void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51634 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19635 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
636 const int sizeof_row = strlen(row);
637 const int num_rows = static_cast<int>(
638 ceil(static_cast<float>(size) / sizeof_row));
639 const int sizeof_data = num_rows * sizeof_row;
640 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43641 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51642
[email protected]4ddaf2502008-10-23 18:26:19643 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43644 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19645}
646
thakis84dff942015-07-28 20:47:38647#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09648uint64_t MockGetMSTime() {
649 // Tue, 23 May 2017 20:13:07 +0000
650 return 131400439870000000;
651}
652
[email protected]385a4672009-03-11 22:21:29653// Alternative functions that eliminate randomness and dependency on the local
654// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37655void MockGenerateRandom(uint8_t* output, size_t n) {
656 // This is set to 0xaa because the client challenge for testing in
657 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
658 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29659}
660
[email protected]fe2bc6a2009-03-23 16:52:20661std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37662 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29663}
thakis84dff942015-07-28 20:47:38664#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29665
[email protected]e60e47a2010-07-14 03:37:18666template<typename ParentPool>
667class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31668 public:
[email protected]9e1bdd32011-02-03 21:48:34669 CaptureGroupNameSocketPool(HostResolver* host_resolver,
670 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18671
[email protected]d80a4322009-08-14 07:07:49672 const std::string last_group_name_received() const {
673 return last_group_name_;
674 }
675
Tarun Bansal162eabe52018-01-20 01:16:39676 bool socket_requested() const { return socket_requested_; }
677
dmichaeld6e570d2014-12-18 22:30:57678 int RequestSocket(const std::string& group_name,
679 const void* socket_params,
680 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54681 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15682 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57683 ClientSocketHandle* handle,
684 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20685 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31686 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39687 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31688 return ERR_IO_PENDING;
689 }
dmichaeld6e570d2014-12-18 22:30:57690 void CancelRequest(const std::string& group_name,
691 ClientSocketHandle* handle) override {}
692 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09693 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57694 int id) override {}
695 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23696 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57697 int IdleSocketCount() const override { return 0; }
698 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31699 return 0;
700 }
dmichaeld6e570d2014-12-18 22:30:57701 LoadState GetLoadState(const std::string& group_name,
702 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31703 return LOAD_STATE_IDLE;
704 }
dmichaeld6e570d2014-12-18 22:30:57705 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26706 return base::TimeDelta();
707 }
[email protected]d80a4322009-08-14 07:07:49708
709 private:
[email protected]04e5be32009-06-26 20:00:31710 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39711 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31712};
713
[email protected]ab739042011-04-07 15:22:28714typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
715CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13716typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
717CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06718typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11719CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18720typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
721CaptureGroupNameSSLSocketPool;
722
rkaplowd90695c2015-03-25 22:12:41723template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18724CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34725 HostResolver* host_resolver,
726 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21727 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18728
hashimoto0d3e4fb2015-01-09 05:02:50729template <>
[email protected]2df19bb2010-08-25 20:13:46730CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21731 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34732 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09733 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46734
[email protected]007b3f82013-04-09 08:46:45735template <>
[email protected]e60e47a2010-07-14 03:37:18736CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21737 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34738 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45739 : SSLClientSocketPool(0,
740 0,
[email protected]007b3f82013-04-09 08:46:45741 cert_verifier,
742 NULL,
743 NULL,
[email protected]284303b62013-11-28 15:11:54744 NULL,
eranm6571b2b2014-12-03 15:53:23745 NULL,
[email protected]007b3f82013-04-09 08:46:45746 std::string(),
747 NULL,
748 NULL,
749 NULL,
750 NULL,
751 NULL,
[email protected]8e458552014-08-05 00:02:15752 NULL) {
753}
[email protected]2227c692010-05-04 15:36:11754
[email protected]231d5a32008-09-13 00:45:27755//-----------------------------------------------------------------------------
756
[email protected]79cb5c12011-09-12 13:12:04757// Helper functions for validating that AuthChallengeInfo's are correctly
758// configured for common cases.
759bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
760 if (!auth_challenge)
761 return false;
762 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43763 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04764 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19765 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04766 return true;
767}
768
769bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
770 if (!auth_challenge)
771 return false;
772 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43773 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
774 EXPECT_EQ("MyRealm1", auth_challenge->realm);
775 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
776 return true;
777}
778
779bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
780 if (!auth_challenge)
781 return false;
782 EXPECT_TRUE(auth_challenge->is_proxy);
783 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04784 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19785 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04786 return true;
787}
788
789bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
790 if (!auth_challenge)
791 return false;
792 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43793 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04794 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19795 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04796 return true;
797}
798
thakis84dff942015-07-28 20:47:38799#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04800bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
801 if (!auth_challenge)
802 return false;
803 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55804 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04805 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19806 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04807 return true;
808}
thakis84dff942015-07-28 20:47:38809#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04810
[email protected]448d4ca52012-03-04 04:12:23811} // namespace
812
bncd16676a2016-07-20 16:23:01813TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27816}
817
bncd16676a2016-07-20 16:23:01818TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27819 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35820 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
821 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06822 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27823 };
[email protected]31a2bfe2010-02-09 08:03:39824 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
825 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01826 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27827 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
828 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22829 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
830 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47831 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59832
833 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27834}
835
836// Response with no status line.
bncd16676a2016-07-20 16:23:01837TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27838 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35839 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06840 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27841 };
[email protected]31a2bfe2010-02-09 08:03:39842 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
843 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41844 EXPECT_THAT(out.rv, IsOk());
845 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
846 EXPECT_EQ("hello world", out.response_data);
847 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
848 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27849}
850
mmenkea7da6da2016-09-01 21:56:52851// Response with no status line, and a weird port. Should fail by default.
852TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
853 MockRead data_reads[] = {
854 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
855 };
856
857 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
858 session_deps_.socket_factory->AddSocketDataProvider(&data);
859
860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
861
krasinc06a72a2016-12-21 03:42:46862 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58863 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19864 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52865
mmenkea7da6da2016-09-01 21:56:52866 request.method = "GET";
867 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10868 request.traffic_annotation =
869 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
870
mmenkea7da6da2016-09-01 21:56:52871 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20872 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52873 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
874}
875
Shivani Sharmafdcaefd2017-11-02 00:12:26876// Tests that request info can be destroyed after the headers phase is complete.
877TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
879 auto trans =
880 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
881
882 MockRead data_reads[] = {
883 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
884 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
885 };
886 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
887 session_deps_.socket_factory->AddSocketDataProvider(&data);
888
889 TestCompletionCallback callback;
890
891 {
892 auto request = std::make_unique<HttpRequestInfo>();
893 request->method = "GET";
894 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10895 request->traffic_annotation =
896 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26897
898 int rv =
899 trans->Start(request.get(), callback.callback(), NetLogWithSource());
900
901 EXPECT_THAT(callback.GetResult(rv), IsOk());
902 } // Let request info be destroyed.
903
904 trans.reset();
905}
906
mmenkea7da6da2016-09-01 21:56:52907// Response with no status line, and a weird port. Option to allow weird ports
908// enabled.
909TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
910 MockRead data_reads[] = {
911 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
912 };
913
914 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
915 session_deps_.socket_factory->AddSocketDataProvider(&data);
916 session_deps_.http_09_on_non_default_ports_enabled = true;
917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
918
krasinc06a72a2016-12-21 03:42:46919 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58920 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19921 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52922
mmenkea7da6da2016-09-01 21:56:52923 request.method = "GET";
924 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10925 request.traffic_annotation =
926 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
927
mmenkea7da6da2016-09-01 21:56:52928 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20929 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52930 EXPECT_THAT(callback.GetResult(rv), IsOk());
931
932 const HttpResponseInfo* info = trans->GetResponseInfo();
933 ASSERT_TRUE(info->headers);
934 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
935
936 // Don't bother to read the body - that's verified elsewhere, important thing
937 // is that the option to allow HTTP/0.9 on non-default ports is respected.
938}
939
[email protected]231d5a32008-09-13 00:45:27940// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01941TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27942 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35943 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06944 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27945 };
[email protected]31a2bfe2010-02-09 08:03:39946 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
947 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01948 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27949 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
950 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22951 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
952 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27953}
954
955// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01956TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27957 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35958 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06959 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27960 };
[email protected]31a2bfe2010-02-09 08:03:39961 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01963 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27964 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
965 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22966 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
967 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27968}
969
970// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01971TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27972 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35973 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06974 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27975 };
[email protected]31a2bfe2010-02-09 08:03:39976 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
977 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41978 EXPECT_THAT(out.rv, IsOk());
979 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
980 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
981 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
982 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27983}
984
985// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01986TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27987 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35988 MockRead("\n"),
989 MockRead("\n"),
990 MockRead("Q"),
991 MockRead("J"),
992 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06993 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27994 };
[email protected]31a2bfe2010-02-09 08:03:39995 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
996 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01997 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27998 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
999 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:221000 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1001 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:271002}
1003
1004// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:011005TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:271006 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351007 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:061008 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:271009 };
[email protected]31a2bfe2010-02-09 08:03:391010 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1011 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411012 EXPECT_THAT(out.rv, IsOk());
1013 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1014 EXPECT_EQ("HTT", out.response_data);
1015 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1016 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521017}
1018
[email protected]f9d44aa2008-09-23 23:57:171019// Simulate a 204 response, lacking a Content-Length header, sent over a
1020// persistent connection. The response should still terminate since a 204
1021// cannot have a response body.
bncd16676a2016-07-20 16:23:011022TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191023 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171024 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351025 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191026 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061027 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171028 };
[email protected]31a2bfe2010-02-09 08:03:391029 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1030 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011031 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171032 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1033 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221034 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1035 int64_t response_size = reads_size - strlen(junk);
1036 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171037}
1038
[email protected]0877e3d2009-10-17 22:29:571039// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011040TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191041 std::string final_chunk = "0\r\n\r\n";
1042 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1043 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571044 MockRead data_reads[] = {
1045 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1046 MockRead("5\r\nHello\r\n"),
1047 MockRead("1\r\n"),
1048 MockRead(" \r\n"),
1049 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191050 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061051 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571052 };
[email protected]31a2bfe2010-02-09 08:03:391053 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1054 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011055 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571056 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1057 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221058 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1059 int64_t response_size = reads_size - extra_data.size();
1060 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571061}
1062
[email protected]9fe44f52010-09-23 18:36:001063// Next tests deal with http://crbug.com/56344.
1064
bncd16676a2016-07-20 16:23:011065TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001066 MultipleContentLengthHeadersNoTransferEncoding) {
1067 MockRead data_reads[] = {
1068 MockRead("HTTP/1.1 200 OK\r\n"),
1069 MockRead("Content-Length: 10\r\n"),
1070 MockRead("Content-Length: 5\r\n\r\n"),
1071 };
1072 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1073 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011074 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001075}
1076
bncd16676a2016-07-20 16:23:011077TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041078 DuplicateContentLengthHeadersNoTransferEncoding) {
1079 MockRead data_reads[] = {
1080 MockRead("HTTP/1.1 200 OK\r\n"),
1081 MockRead("Content-Length: 5\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 MockRead("Hello"),
1084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041088 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1089 EXPECT_EQ("Hello", out.response_data);
1090}
1091
bncd16676a2016-07-20 16:23:011092TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041093 ComplexContentLengthHeadersNoTransferEncoding) {
1094 // More than 2 dupes.
1095 {
1096 MockRead data_reads[] = {
1097 MockRead("HTTP/1.1 200 OK\r\n"),
1098 MockRead("Content-Length: 5\r\n"),
1099 MockRead("Content-Length: 5\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, IsOk());
[email protected]44b52042010-10-29 22:48:041106 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1107 EXPECT_EQ("Hello", out.response_data);
1108 }
1109 // HTTP/1.0
1110 {
1111 MockRead data_reads[] = {
1112 MockRead("HTTP/1.0 200 OK\r\n"),
1113 MockRead("Content-Length: 5\r\n"),
1114 MockRead("Content-Length: 5\r\n"),
1115 MockRead("Content-Length: 5\r\n\r\n"),
1116 MockRead("Hello"),
1117 };
1118 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1119 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011120 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041121 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1122 EXPECT_EQ("Hello", out.response_data);
1123 }
1124 // 2 dupes and one mismatched.
1125 {
1126 MockRead data_reads[] = {
1127 MockRead("HTTP/1.1 200 OK\r\n"),
1128 MockRead("Content-Length: 10\r\n"),
1129 MockRead("Content-Length: 10\r\n"),
1130 MockRead("Content-Length: 5\r\n\r\n"),
1131 };
1132 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1133 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011134 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041135 }
1136}
1137
bncd16676a2016-07-20 16:23:011138TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001139 MultipleContentLengthHeadersTransferEncoding) {
1140 MockRead data_reads[] = {
1141 MockRead("HTTP/1.1 200 OK\r\n"),
1142 MockRead("Content-Length: 666\r\n"),
1143 MockRead("Content-Length: 1337\r\n"),
1144 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1145 MockRead("5\r\nHello\r\n"),
1146 MockRead("1\r\n"),
1147 MockRead(" \r\n"),
1148 MockRead("5\r\nworld\r\n"),
1149 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061150 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001151 };
1152 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1153 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011154 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001155 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1156 EXPECT_EQ("Hello world", out.response_data);
1157}
1158
[email protected]1628fe92011-10-04 23:04:551159// Next tests deal with http://crbug.com/98895.
1160
1161// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011162TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551163 MockRead data_reads[] = {
1164 MockRead("HTTP/1.1 200 OK\r\n"),
1165 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1166 MockRead("Content-Length: 5\r\n\r\n"),
1167 MockRead("Hello"),
1168 };
1169 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1170 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011171 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551172 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1173 EXPECT_EQ("Hello", out.response_data);
1174}
1175
[email protected]54a9c6e52012-03-21 20:10:591176// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011177TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551178 MockRead data_reads[] = {
1179 MockRead("HTTP/1.1 200 OK\r\n"),
1180 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1181 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1182 MockRead("Content-Length: 5\r\n\r\n"),
1183 MockRead("Hello"),
1184 };
1185 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1186 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011187 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591188 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1189 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551190}
1191
1192// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011193TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551194 MockRead data_reads[] = {
1195 MockRead("HTTP/1.1 200 OK\r\n"),
1196 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1197 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1198 MockRead("Content-Length: 5\r\n\r\n"),
1199 MockRead("Hello"),
1200 };
1201 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1202 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011203 EXPECT_THAT(out.rv,
1204 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551205}
1206
[email protected]54a9c6e52012-03-21 20:10:591207// Checks that two identical Location headers result in no error.
1208// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011209TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551210 MockRead data_reads[] = {
1211 MockRead("HTTP/1.1 302 Redirect\r\n"),
1212 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591213 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551214 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061215 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551216 };
1217
1218 HttpRequestInfo request;
1219 request.method = "GET";
1220 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101221 request.traffic_annotation =
1222 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551223
danakj1fd259a02016-04-16 03:17:091224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551226
1227 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071228 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551229
[email protected]49639fa2011-12-20 23:22:411230 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551231
tfarina42834112016-09-22 13:38:201232 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551234
robpercival214763f2016-07-01 23:27:011235 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551236
bnc691fda62016-08-12 00:43:161237 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521238 ASSERT_TRUE(response);
1239 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551240 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1241 std::string url;
1242 EXPECT_TRUE(response->headers->IsRedirect(&url));
1243 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471244 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551245}
1246
[email protected]1628fe92011-10-04 23:04:551247// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011248TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551249 MockRead data_reads[] = {
1250 MockRead("HTTP/1.1 302 Redirect\r\n"),
1251 MockRead("Location: http://good.com/\r\n"),
1252 MockRead("Location: http://evil.com/\r\n"),
1253 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061254 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551255 };
1256 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1257 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011258 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551259}
1260
[email protected]ef0faf2e72009-03-05 23:27:231261// Do a request using the HEAD method. Verify that we don't try to read the
1262// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011263TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421264 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231265 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231266 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101267 request.traffic_annotation =
1268 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231269
danakj1fd259a02016-04-16 03:17:091270 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161271 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091272 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161273 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091274 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1275 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271276
[email protected]ef0faf2e72009-03-05 23:27:231277 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131278 MockWrite("HEAD / HTTP/1.1\r\n"
1279 "Host: www.example.org\r\n"
1280 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231281 };
1282 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231283 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1284 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231285
mmenked39192ee2015-12-09 00:57:231286 // No response body because the test stops reading here.
1287 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231288 };
1289
[email protected]31a2bfe2010-02-09 08:03:391290 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1291 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071292 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231293
[email protected]49639fa2011-12-20 23:22:411294 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231295
tfarina42834112016-09-22 13:38:201296 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231298
1299 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011300 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231301
bnc691fda62016-08-12 00:43:161302 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521303 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231304
1305 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521306 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231307 EXPECT_EQ(1234, response->headers->GetContentLength());
1308 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471309 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091310 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1311 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231312
1313 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101314 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231315 bool has_server_header = response->headers->EnumerateHeader(
1316 &iter, "Server", &server_header);
1317 EXPECT_TRUE(has_server_header);
1318 EXPECT_EQ("Blah", server_header);
1319
1320 // Reading should give EOF right away, since there is no message body
1321 // (despite non-zero content-length).
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]ef0faf2e72009-03-05 23:27:231325 EXPECT_EQ("", response_data);
1326}
1327
bncd16676a2016-07-20 16:23:011328TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521330
1331 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351332 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1333 MockRead("hello"),
1334 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1335 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061336 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521337 };
[email protected]31a2bfe2010-02-09 08:03:391338 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071339 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521340
[email protected]0b0bf032010-09-21 18:08:501341 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521342 "hello", "world"
1343 };
1344
1345 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421346 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521347 request.method = "GET";
bncce36dca22015-04-21 22:11:231348 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101349 request.traffic_annotation =
1350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521351
bnc691fda62016-08-12 00:43:161352 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271353
[email protected]49639fa2011-12-20 23:22:411354 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521355
tfarina42834112016-09-22 13:38:201356 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521358
1359 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011360 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521361
bnc691fda62016-08-12 00:43:161362 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521363 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521364
wezca1070932016-05-26 20:30:521365 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251366 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471367 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521368
1369 std::string response_data;
bnc691fda62016-08-12 00:43:161370 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011371 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251372 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521373 }
1374}
1375
bncd16676a2016-07-20 16:23:011376TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091377 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221378 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191379 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221380 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271381
[email protected]1c773ea12009-04-28 19:58:421382 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521383 request.method = "POST";
1384 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271385 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101386 request.traffic_annotation =
1387 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521388
shivanishab9a143952016-09-19 17:23:411389 // Check the upload progress returned before initialization is correct.
1390 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1391 EXPECT_EQ(0u, progress.size());
1392 EXPECT_EQ(0u, progress.position());
1393
danakj1fd259a02016-04-16 03:17:091394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271396
initial.commit586acc5fe2008-07-26 22:42:521397 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351398 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1399 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1400 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061401 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521402 };
[email protected]31a2bfe2010-02-09 08:03:391403 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071404 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521405
[email protected]49639fa2011-12-20 23:22:411406 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521407
tfarina42834112016-09-22 13:38:201408 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521410
1411 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011412 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521413
bnc691fda62016-08-12 00:43:161414 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521415 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521416
wezca1070932016-05-26 20:30:521417 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251418 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521419
1420 std::string response_data;
bnc691fda62016-08-12 00:43:161421 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011422 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251423 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521424}
1425
[email protected]3a2d3662009-03-27 03:49:141426// This test is almost the same as Ignores100 above, but the response contains
1427// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571428// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011429TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421430 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141431 request.method = "GET";
1432 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101433 request.traffic_annotation =
1434 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141435
danakj1fd259a02016-04-16 03:17:091436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271438
[email protected]3a2d3662009-03-27 03:49:141439 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571440 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1441 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141442 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061443 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141444 };
[email protected]31a2bfe2010-02-09 08:03:391445 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071446 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141447
[email protected]49639fa2011-12-20 23:22:411448 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141449
tfarina42834112016-09-22 13:38:201450 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141452
1453 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011454 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141455
bnc691fda62016-08-12 00:43:161456 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521457 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141458
wezca1070932016-05-26 20:30:521459 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141460 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1461
1462 std::string response_data;
bnc691fda62016-08-12 00:43:161463 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011464 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141465 EXPECT_EQ("hello world", response_data);
1466}
1467
bncd16676a2016-07-20 16:23:011468TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081469 HttpRequestInfo request;
1470 request.method = "POST";
1471 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101472 request.traffic_annotation =
1473 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081474
danakj1fd259a02016-04-16 03:17:091475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081477
1478 MockRead data_reads[] = {
1479 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1480 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381481 };
zmo9528c9f42015-08-04 22:12:081482 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1483 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381484
zmo9528c9f42015-08-04 22:12:081485 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381486
tfarina42834112016-09-22 13:38:201487 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381489
zmo9528c9f42015-08-04 22:12:081490 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011491 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381492
zmo9528c9f42015-08-04 22:12:081493 std::string response_data;
bnc691fda62016-08-12 00:43:161494 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011495 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081496 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381497}
1498
bncd16676a2016-07-20 16:23:011499TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381500 HttpRequestInfo request;
1501 request.method = "POST";
1502 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101503 request.traffic_annotation =
1504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381505
danakj1fd259a02016-04-16 03:17:091506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271508
[email protected]ee9410e72010-01-07 01:42:381509 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061510 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381511 };
[email protected]31a2bfe2010-02-09 08:03:391512 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071513 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381514
[email protected]49639fa2011-12-20 23:22:411515 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381516
tfarina42834112016-09-22 13:38:201517 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381519
1520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011521 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381522}
1523
[email protected]23e482282013-06-14 16:08:021524void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511525 const MockWrite* write_failure,
1526 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421527 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521528 request.method = "GET";
1529 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101530 request.traffic_annotation =
1531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521532
vishal.b62985ca92015-04-17 08:45:511533 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071534 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271536
[email protected]202965992011-12-07 23:04:511537 // Written data for successfully sending both requests.
1538 MockWrite data1_writes[] = {
1539 MockWrite("GET / HTTP/1.1\r\n"
1540 "Host: www.foo.com\r\n"
1541 "Connection: keep-alive\r\n\r\n"),
1542 MockWrite("GET / HTTP/1.1\r\n"
1543 "Host: www.foo.com\r\n"
1544 "Connection: keep-alive\r\n\r\n")
1545 };
1546
1547 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521548 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351549 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1550 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061551 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521552 };
[email protected]202965992011-12-07 23:04:511553
1554 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491555 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511556 data1_writes[1] = *write_failure;
1557 } else {
1558 ASSERT_TRUE(read_failure);
1559 data1_reads[2] = *read_failure;
1560 }
1561
1562 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1563 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071564 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521565
1566 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351567 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1568 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061569 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521570 };
[email protected]31a2bfe2010-02-09 08:03:391571 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071572 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521573
thestig9d3bb0c2015-01-24 00:49:511574 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521575 "hello", "world"
1576 };
1577
mikecironef22f9812016-10-04 03:40:191578 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521579 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411580 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521581
bnc691fda62016-08-12 00:43:161582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521583
tfarina42834112016-09-22 13:38:201584 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521586
1587 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011588 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521589
[email protected]58e32bb2013-01-21 18:23:251590 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161591 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251592 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1593 if (i == 0) {
1594 first_socket_log_id = load_timing_info.socket_log_id;
1595 } else {
1596 // The second request should be using a new socket.
1597 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1598 }
1599
bnc691fda62016-08-12 00:43:161600 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521601 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521602
wezca1070932016-05-26 20:30:521603 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471604 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521606
1607 std::string response_data;
bnc691fda62016-08-12 00:43:161608 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011609 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251610 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521611 }
1612}
[email protected]3d2a59b2008-09-26 19:44:251613
[email protected]a34f61ee2014-03-18 20:59:491614void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1615 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101616 const MockRead* read_failure,
1617 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491618 HttpRequestInfo request;
1619 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101620 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101621 request.traffic_annotation =
1622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491623
vishal.b62985ca92015-04-17 08:45:511624 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491625 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491627
[email protected]09356c652014-03-25 15:36:101628 SSLSocketDataProvider ssl1(ASYNC, OK);
1629 SSLSocketDataProvider ssl2(ASYNC, OK);
1630 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361631 ssl1.next_proto = kProtoHTTP2;
1632 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101633 }
1634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1635 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491636
[email protected]09356c652014-03-25 15:36:101637 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411638 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491639 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411640 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151641 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411642 SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191643 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491644
[email protected]09356c652014-03-25 15:36:101645 // HTTP/1.1 versions of the request and response.
1646 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1647 "Host: www.foo.com\r\n"
1648 "Connection: keep-alive\r\n\r\n";
1649 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1650 const char kHttpData[] = "hello";
1651
1652 std::vector<MockRead> data1_reads;
1653 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491654 if (write_failure) {
1655 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101656 data1_writes.push_back(*write_failure);
1657 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491658 } else {
1659 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101660 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411661 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101662 } else {
1663 data1_writes.push_back(MockWrite(kHttpRequest));
1664 }
1665 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491666 }
1667
[email protected]09356c652014-03-25 15:36:101668 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1669 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491670 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1671
[email protected]09356c652014-03-25 15:36:101672 std::vector<MockRead> data2_reads;
1673 std::vector<MockWrite> data2_writes;
1674
1675 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411676 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101677
bncdf80d44fd2016-07-15 20:27:411678 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1679 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101680 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1681 } else {
1682 data2_writes.push_back(
1683 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1684
1685 data2_reads.push_back(
1686 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1687 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1688 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1689 }
rch8e6c6c42015-05-01 14:05:131690 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1691 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491692 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1693
1694 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591695 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491696 // Wait for the preconnect to complete.
1697 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1698 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101699 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491700
1701 // Make the request.
1702 TestCompletionCallback callback;
1703
bnc691fda62016-08-12 00:43:161704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491705
tfarina42834112016-09-22 13:38:201706 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491708
1709 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011710 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491711
1712 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161713 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101714 TestLoadTimingNotReused(
1715 load_timing_info,
1716 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491717
bnc691fda62016-08-12 00:43:161718 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521719 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491720
wezca1070932016-05-26 20:30:521721 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021722 if (response->was_fetched_via_spdy) {
1723 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1724 } else {
1725 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1726 }
[email protected]a34f61ee2014-03-18 20:59:491727
1728 std::string response_data;
bnc691fda62016-08-12 00:43:161729 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011730 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101731 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491732}
1733
Biljith Jayan45a41722017-08-16 18:43:141734// Test that we do not retry indefinitely when a server sends an error like
1735// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1736// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1737TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1738 HttpRequestInfo request;
1739 request.method = "GET";
1740 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101741 request.traffic_annotation =
1742 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141743
1744 // Check whether we give up after the third try.
1745
1746 // Construct an HTTP2 request and a "Go away" response.
1747 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1748 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291749 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141750 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1751 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1752
1753 // Three go away responses.
1754 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1755 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1756 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1757
1758 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1759 AddSSLSocketData();
1760 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1761 AddSSLSocketData();
1762 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1763 AddSSLSocketData();
1764
1765 TestCompletionCallback callback;
1766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1768
1769 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1771
1772 rv = callback.WaitForResult();
1773 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1774}
1775
1776TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1777 HttpRequestInfo request;
1778 request.method = "GET";
1779 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101780 request.traffic_annotation =
1781 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141782
1783 // Check whether we try atleast thrice before giving up.
1784
1785 // Construct an HTTP2 request and a "Go away" response.
1786 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1787 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291788 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141789 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1790 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1791
1792 // Construct a non error HTTP2 response.
1793 SpdySerializedFrame spdy_response_no_error(
1794 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1795 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1796 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1797 CreateMockRead(spdy_data, 2)};
1798
1799 // Two error responses.
1800 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1801 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1802 // Followed by a success response.
1803 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1804
1805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1806 AddSSLSocketData();
1807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1808 AddSSLSocketData();
1809 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1810 AddSSLSocketData();
1811
1812 TestCompletionCallback callback;
1813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1815
1816 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1818
1819 rv = callback.WaitForResult();
1820 EXPECT_THAT(rv, IsOk());
1821}
1822
bncd16676a2016-07-20 16:23:011823TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061824 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511825 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1826}
1827
bncd16676a2016-07-20 16:23:011828TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061829 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511830 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251831}
1832
bncd16676a2016-07-20 16:23:011833TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061834 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511835 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251836}
1837
[email protected]d58ceea82014-06-04 10:55:541838// Make sure that on a 408 response (Request Timeout), the request is retried,
1839// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011840TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541841 MockRead read_failure(SYNCHRONOUS,
1842 "HTTP/1.1 408 Request Timeout\r\n"
1843 "Connection: Keep-Alive\r\n"
1844 "Content-Length: 6\r\n\r\n"
1845 "Pickle");
1846 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1847}
1848
bncd16676a2016-07-20 16:23:011849TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491850 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101851 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491852}
1853
bncd16676a2016-07-20 16:23:011854TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491855 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101856 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491857}
1858
bncd16676a2016-07-20 16:23:011859TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491860 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101861 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1862}
1863
bncd16676a2016-07-20 16:23:011864TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101865 MockRead read_failure(ASYNC, OK); // EOF
1866 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1867}
1868
[email protected]d58ceea82014-06-04 10:55:541869// Make sure that on a 408 response (Request Timeout), the request is retried,
1870// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011871TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541872 MockRead read_failure(SYNCHRONOUS,
1873 "HTTP/1.1 408 Request Timeout\r\n"
1874 "Connection: Keep-Alive\r\n"
1875 "Content-Length: 6\r\n\r\n"
1876 "Pickle");
1877 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1878 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1879}
1880
bncd16676a2016-07-20 16:23:011881TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101882 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1883 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1884}
1885
bncd16676a2016-07-20 16:23:011886TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101887 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1888 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1889}
1890
bncd16676a2016-07-20 16:23:011891TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101892 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1893 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1894}
1895
bncd16676a2016-07-20 16:23:011896TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101897 MockRead read_failure(ASYNC, OK); // EOF
1898 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491899}
1900
bncd16676a2016-07-20 16:23:011901TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421902 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251903 request.method = "GET";
bncce36dca22015-04-21 22:11:231904 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101905 request.traffic_annotation =
1906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251907
danakj1fd259a02016-04-16 03:17:091908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271910
[email protected]3d2a59b2008-09-26 19:44:251911 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061912 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351913 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1914 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061915 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251916 };
[email protected]31a2bfe2010-02-09 08:03:391917 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071918 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251919
[email protected]49639fa2011-12-20 23:22:411920 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251921
tfarina42834112016-09-22 13:38:201922 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251924
1925 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011926 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591927
1928 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161929 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591930 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251931}
1932
1933// What do various browsers do when the server closes a non-keepalive
1934// connection without sending any response header or body?
1935//
1936// IE7: error page
1937// Safari 3.1.2 (Windows): error page
1938// Firefox 3.0.1: blank page
1939// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421940// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1941// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011942TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251943 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061944 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351945 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1946 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061947 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251948 };
[email protected]31a2bfe2010-02-09 08:03:391949 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1950 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011951 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251952}
[email protected]1826a402014-01-08 15:40:481953
[email protected]7a5378b2012-11-04 03:25:171954// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1955// tests. There was a bug causing HttpNetworkTransaction to hang in the
1956// destructor in such situations.
1957// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011958TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171959 HttpRequestInfo request;
1960 request.method = "GET";
bncce36dca22015-04-21 22:11:231961 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101962 request.traffic_annotation =
1963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171964
danakj1fd259a02016-04-16 03:17:091965 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581966 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191967 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171968
1969 MockRead data_reads[] = {
1970 MockRead("HTTP/1.0 200 OK\r\n"),
1971 MockRead("Connection: keep-alive\r\n"),
1972 MockRead("Content-Length: 100\r\n\r\n"),
1973 MockRead("hello"),
1974 MockRead(SYNCHRONOUS, 0),
1975 };
1976 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071977 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171978
1979 TestCompletionCallback callback;
1980
tfarina42834112016-09-22 13:38:201981 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171983
1984 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011985 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171986
1987 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501988 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171989 if (rv == ERR_IO_PENDING)
1990 rv = callback.WaitForResult();
1991 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501992 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011993 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171994
1995 trans.reset();
fdoray92e35a72016-06-10 15:54:551996 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171997 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1998}
1999
bncd16676a2016-07-20 16:23:012000TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172001 HttpRequestInfo request;
2002 request.method = "GET";
bncce36dca22015-04-21 22:11:232003 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102004 request.traffic_annotation =
2005 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172006
danakj1fd259a02016-04-16 03:17:092007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582008 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192009 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172010
2011 MockRead data_reads[] = {
2012 MockRead("HTTP/1.0 200 OK\r\n"),
2013 MockRead("Connection: keep-alive\r\n"),
2014 MockRead("Content-Length: 100\r\n\r\n"),
2015 MockRead(SYNCHRONOUS, 0),
2016 };
2017 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072018 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172019
2020 TestCompletionCallback callback;
2021
tfarina42834112016-09-22 13:38:202022 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172024
2025 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012026 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172027
2028 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:502029 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172030 if (rv == ERR_IO_PENDING)
2031 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012032 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172033
2034 trans.reset();
fdoray92e35a72016-06-10 15:54:552035 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172036 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2037}
2038
[email protected]0b0bf032010-09-21 18:08:502039// Test that we correctly reuse a keep-alive connection after not explicitly
2040// reading the body.
bncd16676a2016-07-20 16:23:012041TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132042 HttpRequestInfo request;
2043 request.method = "GET";
2044 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102045 request.traffic_annotation =
2046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132047
vishal.b62985ca92015-04-17 08:45:512048 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072049 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092050 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272051
mmenkecc2298e2015-12-07 18:20:182052 const char* request_data =
2053 "GET / HTTP/1.1\r\n"
2054 "Host: www.foo.com\r\n"
2055 "Connection: keep-alive\r\n\r\n";
2056 MockWrite data_writes[] = {
2057 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2058 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2059 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2060 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2061 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2062 };
2063
[email protected]0b0bf032010-09-21 18:08:502064 // Note that because all these reads happen in the same
2065 // StaticSocketDataProvider, it shows that the same socket is being reused for
2066 // all transactions.
mmenkecc2298e2015-12-07 18:20:182067 MockRead data_reads[] = {
2068 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2069 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2070 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2071 MockRead(ASYNC, 7,
2072 "HTTP/1.1 302 Found\r\n"
2073 "Content-Length: 0\r\n\r\n"),
2074 MockRead(ASYNC, 9,
2075 "HTTP/1.1 302 Found\r\n"
2076 "Content-Length: 5\r\n\r\n"
2077 "hello"),
2078 MockRead(ASYNC, 11,
2079 "HTTP/1.1 301 Moved Permanently\r\n"
2080 "Content-Length: 0\r\n\r\n"),
2081 MockRead(ASYNC, 13,
2082 "HTTP/1.1 301 Moved Permanently\r\n"
2083 "Content-Length: 5\r\n\r\n"
2084 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132085
mmenkecc2298e2015-12-07 18:20:182086 // In the next two rounds, IsConnectedAndIdle returns false, due to
2087 // the set_busy_before_sync_reads(true) call, while the
2088 // HttpNetworkTransaction is being shut down, but the socket is still
2089 // reuseable. See http://crbug.com/544255.
2090 MockRead(ASYNC, 15,
2091 "HTTP/1.1 200 Hunky-Dory\r\n"
2092 "Content-Length: 5\r\n\r\n"),
2093 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132094
mmenkecc2298e2015-12-07 18:20:182095 MockRead(ASYNC, 18,
2096 "HTTP/1.1 200 Hunky-Dory\r\n"
2097 "Content-Length: 5\r\n\r\n"
2098 "he"),
2099 MockRead(SYNCHRONOUS, 19, "llo"),
2100
2101 // The body of the final request is actually read.
2102 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2103 MockRead(ASYNC, 22, "hello"),
2104 };
2105 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2106 arraysize(data_writes));
2107 data.set_busy_before_sync_reads(true);
2108 session_deps_.socket_factory->AddSocketDataProvider(&data);
2109
2110 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502111 std::string response_lines[kNumUnreadBodies];
2112
mikecironef22f9812016-10-04 03:40:192113 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182114 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412115 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132116
Jeremy Roman0579ed62017-08-29 15:56:192117 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582118 session.get());
[email protected]fc31d6a42010-06-24 18:05:132119
tfarina42834112016-09-22 13:38:202120 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132122
[email protected]58e32bb2013-01-21 18:23:252123 LoadTimingInfo load_timing_info;
2124 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2125 if (i == 0) {
2126 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2127 first_socket_log_id = load_timing_info.socket_log_id;
2128 } else {
2129 TestLoadTimingReused(load_timing_info);
2130 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2131 }
2132
[email protected]fc31d6a42010-06-24 18:05:132133 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182134 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132135
mmenkecc2298e2015-12-07 18:20:182136 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502137 response_lines[i] = response->headers->GetStatusLine();
2138
mmenkecc2298e2015-12-07 18:20:182139 // Delete the transaction without reading the response bodies. Then spin
2140 // the message loop, so the response bodies are drained.
2141 trans.reset();
2142 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132143 }
[email protected]0b0bf032010-09-21 18:08:502144
2145 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182146 "HTTP/1.1 204 No Content",
2147 "HTTP/1.1 205 Reset Content",
2148 "HTTP/1.1 304 Not Modified",
2149 "HTTP/1.1 302 Found",
2150 "HTTP/1.1 302 Found",
2151 "HTTP/1.1 301 Moved Permanently",
2152 "HTTP/1.1 301 Moved Permanently",
2153 "HTTP/1.1 200 Hunky-Dory",
2154 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502155 };
2156
mostynb91e0da982015-01-20 19:17:272157 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2158 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502159
2160 for (int i = 0; i < kNumUnreadBodies; ++i)
2161 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2162
[email protected]49639fa2011-12-20 23:22:412163 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202165 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012166 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162167 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182168 ASSERT_TRUE(response);
2169 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502170 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2171 std::string response_data;
bnc691fda62016-08-12 00:43:162172 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012173 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502174 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132175}
2176
mmenke5f94fda2016-06-02 20:54:132177// Sockets that receive extra data after a response is complete should not be
2178// reused.
bncd16676a2016-07-20 16:23:012179TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2181 MockWrite data_writes1[] = {
2182 MockWrite("HEAD / HTTP/1.1\r\n"
2183 "Host: www.borked.com\r\n"
2184 "Connection: keep-alive\r\n\r\n"),
2185 };
2186
2187 MockRead data_reads1[] = {
2188 MockRead("HTTP/1.1 200 OK\r\n"
2189 "Connection: keep-alive\r\n"
2190 "Content-Length: 22\r\n\r\n"
2191 "This server is borked."),
2192 };
2193
2194 MockWrite data_writes2[] = {
2195 MockWrite("GET /foo HTTP/1.1\r\n"
2196 "Host: www.borked.com\r\n"
2197 "Connection: keep-alive\r\n\r\n"),
2198 };
2199
2200 MockRead data_reads2[] = {
2201 MockRead("HTTP/1.1 200 OK\r\n"
2202 "Content-Length: 3\r\n\r\n"
2203 "foo"),
2204 };
2205 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2206 data_writes1, arraysize(data_writes1));
2207 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2208 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2209 data_writes2, arraysize(data_writes2));
2210 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2211
2212 TestCompletionCallback callback;
2213 HttpRequestInfo request1;
2214 request1.method = "HEAD";
2215 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102216 request1.traffic_annotation =
2217 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132218
bnc87dcefc2017-05-25 12:47:582219 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192220 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202221 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012222 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132223
2224 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2225 ASSERT_TRUE(response1);
2226 ASSERT_TRUE(response1->headers);
2227 EXPECT_EQ(200, response1->headers->response_code());
2228 EXPECT_TRUE(response1->headers->IsKeepAlive());
2229
2230 std::string response_data1;
robpercival214763f2016-07-01 23:27:012231 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132232 EXPECT_EQ("", response_data1);
2233 // Deleting the transaction attempts to release the socket back into the
2234 // socket pool.
2235 trans1.reset();
2236
2237 HttpRequestInfo request2;
2238 request2.method = "GET";
2239 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102240 request2.traffic_annotation =
2241 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132242
bnc87dcefc2017-05-25 12:47:582243 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192244 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202245 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012246 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132247
2248 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2249 ASSERT_TRUE(response2);
2250 ASSERT_TRUE(response2->headers);
2251 EXPECT_EQ(200, response2->headers->response_code());
2252
2253 std::string response_data2;
robpercival214763f2016-07-01 23:27:012254 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132255 EXPECT_EQ("foo", response_data2);
2256}
2257
bncd16676a2016-07-20 16:23:012258TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2260 MockWrite data_writes1[] = {
2261 MockWrite("GET / HTTP/1.1\r\n"
2262 "Host: www.borked.com\r\n"
2263 "Connection: keep-alive\r\n\r\n"),
2264 };
2265
2266 MockRead data_reads1[] = {
2267 MockRead("HTTP/1.1 200 OK\r\n"
2268 "Connection: keep-alive\r\n"
2269 "Content-Length: 22\r\n\r\n"
2270 "This server is borked."
2271 "Bonus data!"),
2272 };
2273
2274 MockWrite data_writes2[] = {
2275 MockWrite("GET /foo HTTP/1.1\r\n"
2276 "Host: www.borked.com\r\n"
2277 "Connection: keep-alive\r\n\r\n"),
2278 };
2279
2280 MockRead data_reads2[] = {
2281 MockRead("HTTP/1.1 200 OK\r\n"
2282 "Content-Length: 3\r\n\r\n"
2283 "foo"),
2284 };
2285 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2286 data_writes1, arraysize(data_writes1));
2287 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2288 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2289 data_writes2, arraysize(data_writes2));
2290 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2291
2292 TestCompletionCallback callback;
2293 HttpRequestInfo request1;
2294 request1.method = "GET";
2295 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102296 request1.traffic_annotation =
2297 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132298
bnc87dcefc2017-05-25 12:47:582299 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192300 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202301 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012302 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132303
2304 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2305 ASSERT_TRUE(response1);
2306 ASSERT_TRUE(response1->headers);
2307 EXPECT_EQ(200, response1->headers->response_code());
2308 EXPECT_TRUE(response1->headers->IsKeepAlive());
2309
2310 std::string response_data1;
robpercival214763f2016-07-01 23:27:012311 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132312 EXPECT_EQ("This server is borked.", response_data1);
2313 // Deleting the transaction attempts to release the socket back into the
2314 // socket pool.
2315 trans1.reset();
2316
2317 HttpRequestInfo request2;
2318 request2.method = "GET";
2319 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102320 request2.traffic_annotation =
2321 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132322
bnc87dcefc2017-05-25 12:47:582323 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192324 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202325 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012326 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132327
2328 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2329 ASSERT_TRUE(response2);
2330 ASSERT_TRUE(response2->headers);
2331 EXPECT_EQ(200, response2->headers->response_code());
2332
2333 std::string response_data2;
robpercival214763f2016-07-01 23:27:012334 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132335 EXPECT_EQ("foo", response_data2);
2336}
2337
bncd16676a2016-07-20 16:23:012338TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2340 MockWrite data_writes1[] = {
2341 MockWrite("GET / HTTP/1.1\r\n"
2342 "Host: www.borked.com\r\n"
2343 "Connection: keep-alive\r\n\r\n"),
2344 };
2345
2346 MockRead data_reads1[] = {
2347 MockRead("HTTP/1.1 200 OK\r\n"
2348 "Connection: keep-alive\r\n"
2349 "Transfer-Encoding: chunked\r\n\r\n"),
2350 MockRead("16\r\nThis server is borked.\r\n"),
2351 MockRead("0\r\n\r\nBonus data!"),
2352 };
2353
2354 MockWrite data_writes2[] = {
2355 MockWrite("GET /foo HTTP/1.1\r\n"
2356 "Host: www.borked.com\r\n"
2357 "Connection: keep-alive\r\n\r\n"),
2358 };
2359
2360 MockRead data_reads2[] = {
2361 MockRead("HTTP/1.1 200 OK\r\n"
2362 "Content-Length: 3\r\n\r\n"
2363 "foo"),
2364 };
2365 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2366 data_writes1, arraysize(data_writes1));
2367 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2368 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2369 data_writes2, arraysize(data_writes2));
2370 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2371
2372 TestCompletionCallback callback;
2373 HttpRequestInfo request1;
2374 request1.method = "GET";
2375 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102376 request1.traffic_annotation =
2377 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132378
bnc87dcefc2017-05-25 12:47:582379 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192380 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202381 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012382 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132383
2384 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2385 ASSERT_TRUE(response1);
2386 ASSERT_TRUE(response1->headers);
2387 EXPECT_EQ(200, response1->headers->response_code());
2388 EXPECT_TRUE(response1->headers->IsKeepAlive());
2389
2390 std::string response_data1;
robpercival214763f2016-07-01 23:27:012391 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132392 EXPECT_EQ("This server is borked.", response_data1);
2393 // Deleting the transaction attempts to release the socket back into the
2394 // socket pool.
2395 trans1.reset();
2396
2397 HttpRequestInfo request2;
2398 request2.method = "GET";
2399 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102400 request2.traffic_annotation =
2401 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132402
bnc87dcefc2017-05-25 12:47:582403 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192404 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202405 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012406 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132407
2408 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2409 ASSERT_TRUE(response2);
2410 ASSERT_TRUE(response2->headers);
2411 EXPECT_EQ(200, response2->headers->response_code());
2412
2413 std::string response_data2;
robpercival214763f2016-07-01 23:27:012414 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132415 EXPECT_EQ("foo", response_data2);
2416}
2417
2418// This is a little different from the others - it tests the case that the
2419// HttpStreamParser doesn't know if there's extra data on a socket or not when
2420// the HttpNetworkTransaction is torn down, because the response body hasn't
2421// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012422TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132423 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2424 MockWrite data_writes1[] = {
2425 MockWrite("GET / HTTP/1.1\r\n"
2426 "Host: www.borked.com\r\n"
2427 "Connection: keep-alive\r\n\r\n"),
2428 };
2429
2430 MockRead data_reads1[] = {
2431 MockRead("HTTP/1.1 200 OK\r\n"
2432 "Connection: keep-alive\r\n"
2433 "Transfer-Encoding: chunked\r\n\r\n"),
2434 MockRead("16\r\nThis server is borked.\r\n"),
2435 MockRead("0\r\n\r\nBonus data!"),
2436 };
2437 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2438 data_writes1, arraysize(data_writes1));
2439 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2440
2441 TestCompletionCallback callback;
2442 HttpRequestInfo request1;
2443 request1.method = "GET";
2444 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102445 request1.traffic_annotation =
2446 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132447
bnc87dcefc2017-05-25 12:47:582448 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192449 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582450 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012451 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132452
bnc87dcefc2017-05-25 12:47:582453 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132454 ASSERT_TRUE(response1);
2455 ASSERT_TRUE(response1->headers);
2456 EXPECT_EQ(200, response1->headers->response_code());
2457 EXPECT_TRUE(response1->headers->IsKeepAlive());
2458
2459 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2460 // response body.
bnc87dcefc2017-05-25 12:47:582461 trans.reset();
mmenke5f94fda2016-06-02 20:54:132462
2463 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2464 // socket can't be reused, rather than returning it to the socket pool.
2465 base::RunLoop().RunUntilIdle();
2466
2467 // There should be no idle sockets in the pool.
2468 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2469}
2470
[email protected]038e9a32008-10-08 22:40:162471// Test the request-challenge-retry sequence for basic auth.
2472// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012473TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422474 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162475 request.method = "GET";
bncce36dca22015-04-21 22:11:232476 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102477 request.traffic_annotation =
2478 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162479
vishal.b62985ca92015-04-17 08:45:512480 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072481 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272484
[email protected]f9ee6b52008-11-08 06:46:232485 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232486 MockWrite(
2487 "GET / HTTP/1.1\r\n"
2488 "Host: www.example.org\r\n"
2489 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232490 };
2491
[email protected]038e9a32008-10-08 22:40:162492 MockRead data_reads1[] = {
2493 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2494 // Give a couple authenticate options (only the middle one is actually
2495 // supported).
[email protected]22927ad2009-09-21 19:56:192496 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162497 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2498 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2499 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2500 // Large content-length -- won't matter, as connection will be reset.
2501 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062502 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162503 };
2504
2505 // After calling trans->RestartWithAuth(), this is the request we should
2506 // be issuing -- the final header line contains the credentials.
2507 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232508 MockWrite(
2509 "GET / HTTP/1.1\r\n"
2510 "Host: www.example.org\r\n"
2511 "Connection: keep-alive\r\n"
2512 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162513 };
2514
2515 // Lastly, the server responds with the actual content.
2516 MockRead data_reads2[] = {
2517 MockRead("HTTP/1.0 200 OK\r\n"),
2518 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2519 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062520 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162521 };
2522
[email protected]31a2bfe2010-02-09 08:03:392523 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2524 data_writes1, arraysize(data_writes1));
2525 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2526 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2528 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162529
[email protected]49639fa2011-12-20 23:22:412530 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162531
tfarina42834112016-09-22 13:38:202532 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162534
2535 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012536 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162537
[email protected]58e32bb2013-01-21 18:23:252538 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162539 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252540 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2541
sclittlefb249892015-09-10 21:33:222542 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162543 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222544 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162545 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192546
bnc691fda62016-08-12 00:43:162547 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522548 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042549 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162550
[email protected]49639fa2011-12-20 23:22:412551 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162552
bnc691fda62016-08-12 00:43:162553 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162555
2556 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012557 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162558
[email protected]58e32bb2013-01-21 18:23:252559 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162560 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252561 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2562 // The load timing after restart should have a new socket ID, and times after
2563 // those of the first load timing.
2564 EXPECT_LE(load_timing_info1.receive_headers_end,
2565 load_timing_info2.connect_timing.connect_start);
2566 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2567
sclittlefb249892015-09-10 21:33:222568 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162569 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222570 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162571 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192572
bnc691fda62016-08-12 00:43:162573 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522574 ASSERT_TRUE(response);
2575 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162576 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162577}
2578
ttuttled9dbc652015-09-29 20:00:592579// Test the request-challenge-retry sequence for basic auth.
2580// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012581TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592582 HttpRequestInfo request;
2583 request.method = "GET";
2584 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102585 request.traffic_annotation =
2586 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592587
2588 TestNetLog log;
2589 MockHostResolver* resolver = new MockHostResolver();
2590 session_deps_.net_log = &log;
2591 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092592 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592594
2595 resolver->rules()->ClearRules();
2596 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2597
2598 MockWrite data_writes1[] = {
2599 MockWrite("GET / HTTP/1.1\r\n"
2600 "Host: www.example.org\r\n"
2601 "Connection: keep-alive\r\n\r\n"),
2602 };
2603
2604 MockRead data_reads1[] = {
2605 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2606 // Give a couple authenticate options (only the middle one is actually
2607 // supported).
2608 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2609 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2610 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2611 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2612 // Large content-length -- won't matter, as connection will be reset.
2613 MockRead("Content-Length: 10000\r\n\r\n"),
2614 MockRead(SYNCHRONOUS, ERR_FAILED),
2615 };
2616
2617 // After calling trans->RestartWithAuth(), this is the request we should
2618 // be issuing -- the final header line contains the credentials.
2619 MockWrite data_writes2[] = {
2620 MockWrite("GET / HTTP/1.1\r\n"
2621 "Host: www.example.org\r\n"
2622 "Connection: keep-alive\r\n"
2623 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2624 };
2625
2626 // Lastly, the server responds with the actual content.
2627 MockRead data_reads2[] = {
2628 MockRead("HTTP/1.0 200 OK\r\n"),
2629 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2630 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2631 };
2632
2633 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2634 data_writes1, arraysize(data_writes1));
2635 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2636 data_writes2, arraysize(data_writes2));
2637 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2638 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2639
2640 TestCompletionCallback callback1;
2641
bnc691fda62016-08-12 00:43:162642 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202643 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592644
2645 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162646 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592647 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2648
2649 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162650 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592651 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162652 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592653
bnc691fda62016-08-12 00:43:162654 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592655 ASSERT_TRUE(response);
2656 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2657
2658 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162659 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592660 ASSERT_FALSE(endpoint.address().empty());
2661 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2662
2663 resolver->rules()->ClearRules();
2664 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2665
2666 TestCompletionCallback callback2;
2667
bnc691fda62016-08-12 00:43:162668 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592669 AuthCredentials(kFoo, kBar), callback2.callback())));
2670
2671 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162672 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592673 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2674 // The load timing after restart should have a new socket ID, and times after
2675 // those of the first load timing.
2676 EXPECT_LE(load_timing_info1.receive_headers_end,
2677 load_timing_info2.connect_timing.connect_start);
2678 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2679
2680 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162681 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592682 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162683 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592684
bnc691fda62016-08-12 00:43:162685 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592686 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522687 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592688 EXPECT_EQ(100, response->headers->GetContentLength());
2689
bnc691fda62016-08-12 00:43:162690 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592691 ASSERT_FALSE(endpoint.address().empty());
2692 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2693}
2694
bncd16676a2016-07-20 16:23:012695TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462696 HttpRequestInfo request;
2697 request.method = "GET";
bncce36dca22015-04-21 22:11:232698 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292699 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102700 request.traffic_annotation =
2701 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462702
danakj1fd259a02016-04-16 03:17:092703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272705
[email protected]861fcd52009-08-26 02:33:462706 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232707 MockWrite(
2708 "GET / HTTP/1.1\r\n"
2709 "Host: www.example.org\r\n"
2710 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462711 };
2712
2713 MockRead data_reads[] = {
2714 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2715 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2716 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2717 // Large content-length -- won't matter, as connection will be reset.
2718 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062719 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462720 };
2721
[email protected]31a2bfe2010-02-09 08:03:392722 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2723 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072724 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412725 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462726
tfarina42834112016-09-22 13:38:202727 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462729
2730 rv = callback.WaitForResult();
2731 EXPECT_EQ(0, rv);
2732
sclittlefb249892015-09-10 21:33:222733 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162734 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222735 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162736 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192737
bnc691fda62016-08-12 00:43:162738 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522739 ASSERT_TRUE(response);
2740 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462741}
2742
[email protected]2d2697f92009-02-18 21:00:322743// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2744// connection.
bncd16676a2016-07-20 16:23:012745TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182746 // On the second pass, the body read of the auth challenge is synchronous, so
2747 // IsConnectedAndIdle returns false. The socket should still be drained and
2748 // reused. See http://crbug.com/544255.
2749 for (int i = 0; i < 2; ++i) {
2750 HttpRequestInfo request;
2751 request.method = "GET";
2752 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102753 request.traffic_annotation =
2754 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322755
mmenkecc2298e2015-12-07 18:20:182756 TestNetLog log;
2757 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272759
mmenkecc2298e2015-12-07 18:20:182760 MockWrite data_writes[] = {
2761 MockWrite(ASYNC, 0,
2762 "GET / HTTP/1.1\r\n"
2763 "Host: www.example.org\r\n"
2764 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322765
bnc691fda62016-08-12 00:43:162766 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182767 // be issuing -- the final header line contains the credentials.
2768 MockWrite(ASYNC, 6,
2769 "GET / HTTP/1.1\r\n"
2770 "Host: www.example.org\r\n"
2771 "Connection: keep-alive\r\n"
2772 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2773 };
[email protected]2d2697f92009-02-18 21:00:322774
mmenkecc2298e2015-12-07 18:20:182775 MockRead data_reads[] = {
2776 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2777 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2778 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2779 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2780 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322781
mmenkecc2298e2015-12-07 18:20:182782 // Lastly, the server responds with the actual content.
2783 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2784 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2785 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2786 MockRead(ASYNC, 10, "Hello"),
2787 };
[email protected]2d2697f92009-02-18 21:00:322788
mmenkecc2298e2015-12-07 18:20:182789 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2790 arraysize(data_writes));
2791 data.set_busy_before_sync_reads(true);
2792 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462793
mmenkecc2298e2015-12-07 18:20:182794 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322795
bnc691fda62016-08-12 00:43:162796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202797 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012798 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322799
mmenkecc2298e2015-12-07 18:20:182800 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162801 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182802 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322803
bnc691fda62016-08-12 00:43:162804 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182805 ASSERT_TRUE(response);
2806 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322807
mmenkecc2298e2015-12-07 18:20:182808 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252809
bnc691fda62016-08-12 00:43:162810 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2811 callback2.callback());
robpercival214763f2016-07-01 23:27:012812 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322813
mmenkecc2298e2015-12-07 18:20:182814 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162815 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182816 TestLoadTimingReused(load_timing_info2);
2817 // The load timing after restart should have the same socket ID, and times
2818 // those of the first load timing.
2819 EXPECT_LE(load_timing_info1.receive_headers_end,
2820 load_timing_info2.send_start);
2821 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322822
bnc691fda62016-08-12 00:43:162823 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182824 ASSERT_TRUE(response);
2825 EXPECT_FALSE(response->auth_challenge);
2826 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322827
mmenkecc2298e2015-12-07 18:20:182828 std::string response_data;
bnc691fda62016-08-12 00:43:162829 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322830
mmenkecc2298e2015-12-07 18:20:182831 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162832 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182833 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162834 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182835 }
[email protected]2d2697f92009-02-18 21:00:322836}
2837
2838// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2839// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012840TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422841 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322842 request.method = "GET";
bncce36dca22015-04-21 22:11:232843 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102844 request.traffic_annotation =
2845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322846
danakj1fd259a02016-04-16 03:17:092847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272848
[email protected]2d2697f92009-02-18 21:00:322849 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162850 MockWrite("GET / HTTP/1.1\r\n"
2851 "Host: www.example.org\r\n"
2852 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322853
bnc691fda62016-08-12 00:43:162854 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232855 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162856 MockWrite("GET / HTTP/1.1\r\n"
2857 "Host: www.example.org\r\n"
2858 "Connection: keep-alive\r\n"
2859 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322860 };
2861
[email protected]2d2697f92009-02-18 21:00:322862 MockRead data_reads1[] = {
2863 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2864 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312865 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322866
2867 // Lastly, the server responds with the actual content.
2868 MockRead("HTTP/1.1 200 OK\r\n"),
2869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502870 MockRead("Content-Length: 5\r\n\r\n"),
2871 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322872 };
2873
[email protected]2d0a4f92011-05-05 16:38:462874 // An incorrect reconnect would cause this to be read.
2875 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062876 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462877 };
2878
[email protected]31a2bfe2010-02-09 08:03:392879 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2880 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462881 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2882 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072883 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2884 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322885
[email protected]49639fa2011-12-20 23:22:412886 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322887
bnc691fda62016-08-12 00:43:162888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202889 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322891
2892 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012893 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322894
bnc691fda62016-08-12 00:43:162895 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522896 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042897 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322898
[email protected]49639fa2011-12-20 23:22:412899 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322900
bnc691fda62016-08-12 00:43:162901 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322903
2904 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012905 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322906
bnc691fda62016-08-12 00:43:162907 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522908 ASSERT_TRUE(response);
2909 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502910 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322911}
2912
2913// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2914// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012915TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422916 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322917 request.method = "GET";
bncce36dca22015-04-21 22:11:232918 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102919 request.traffic_annotation =
2920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322921
danakj1fd259a02016-04-16 03:17:092922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272923
[email protected]2d2697f92009-02-18 21:00:322924 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162925 MockWrite("GET / HTTP/1.1\r\n"
2926 "Host: www.example.org\r\n"
2927 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322928
bnc691fda62016-08-12 00:43:162929 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232930 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162931 MockWrite("GET / HTTP/1.1\r\n"
2932 "Host: www.example.org\r\n"
2933 "Connection: keep-alive\r\n"
2934 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322935 };
2936
2937 // Respond with 5 kb of response body.
2938 std::string large_body_string("Unauthorized");
2939 large_body_string.append(5 * 1024, ' ');
2940 large_body_string.append("\r\n");
2941
2942 MockRead data_reads1[] = {
2943 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2944 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2945 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2946 // 5134 = 12 + 5 * 1024 + 2
2947 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062948 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322949
2950 // Lastly, the server responds with the actual content.
2951 MockRead("HTTP/1.1 200 OK\r\n"),
2952 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502953 MockRead("Content-Length: 5\r\n\r\n"),
2954 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322955 };
2956
[email protected]2d0a4f92011-05-05 16:38:462957 // An incorrect reconnect would cause this to be read.
2958 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062959 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462960 };
2961
[email protected]31a2bfe2010-02-09 08:03:392962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2963 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462964 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2965 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2967 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322968
[email protected]49639fa2011-12-20 23:22:412969 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322970
bnc691fda62016-08-12 00:43:162971 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202972 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322974
2975 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012976 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322977
bnc691fda62016-08-12 00:43:162978 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522979 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042980 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322981
[email protected]49639fa2011-12-20 23:22:412982 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322983
bnc691fda62016-08-12 00:43:162984 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322986
2987 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012988 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322989
bnc691fda62016-08-12 00:43:162990 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522991 ASSERT_TRUE(response);
2992 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502993 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322994}
2995
2996// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312997// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012998TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312999 HttpRequestInfo request;
3000 request.method = "GET";
bncce36dca22015-04-21 22:11:233001 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103002 request.traffic_annotation =
3003 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313004
danakj1fd259a02016-04-16 03:17:093005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273006
[email protected]11203f012009-11-12 23:02:313007 MockWrite data_writes1[] = {
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\r\n"),
3012 // This simulates the seemingly successful write to a closed connection
3013 // if the bug is not fixed.
3014 MockWrite(
3015 "GET / HTTP/1.1\r\n"
3016 "Host: www.example.org\r\n"
3017 "Connection: keep-alive\r\n"
3018 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313019 };
3020
3021 MockRead data_reads1[] = {
3022 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3023 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3024 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3025 MockRead("Content-Length: 14\r\n\r\n"),
3026 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063027 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313028 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063029 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313030 };
3031
bnc691fda62016-08-12 00:43:163032 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313033 // be issuing -- the final header line contains the credentials.
3034 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233035 MockWrite(
3036 "GET / HTTP/1.1\r\n"
3037 "Host: www.example.org\r\n"
3038 "Connection: keep-alive\r\n"
3039 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313040 };
3041
3042 // Lastly, the server responds with the actual content.
3043 MockRead data_reads2[] = {
3044 MockRead("HTTP/1.1 200 OK\r\n"),
3045 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503046 MockRead("Content-Length: 5\r\n\r\n"),
3047 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313048 };
3049
[email protected]31a2bfe2010-02-09 08:03:393050 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3051 data_writes1, arraysize(data_writes1));
3052 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3053 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073054 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3055 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313056
[email protected]49639fa2011-12-20 23:22:413057 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313058
bnc691fda62016-08-12 00:43:163059 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203060 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313062
3063 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013064 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313065
bnc691fda62016-08-12 00:43:163066 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523067 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043068 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313069
[email protected]49639fa2011-12-20 23:22:413070 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313071
bnc691fda62016-08-12 00:43:163072 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313074
3075 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013076 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313077
bnc691fda62016-08-12 00:43:163078 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523079 ASSERT_TRUE(response);
3080 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503081 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313082}
3083
[email protected]394816e92010-08-03 07:38:593084// Test the request-challenge-retry sequence for basic auth, over a connection
3085// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013086TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013087 HttpRequestInfo request;
3088 request.method = "GET";
bncce36dca22015-04-21 22:11:233089 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013090 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293091 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103092 request.traffic_annotation =
3093 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013094
3095 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593096 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493097 ProxyResolutionService::CreateFixedFromPacResult(
3098 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513099 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013100 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093101 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013102
3103 // Since we have proxy, should try to establish tunnel.
3104 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543105 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173106 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543107 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013108 };
3109
mmenkee71e15332015-10-07 16:39:543110 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013111 // connection.
3112 MockRead data_reads1[] = {
3113 // No credentials.
3114 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3115 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543116 };
ttuttle34f63b52015-03-05 04:33:013117
mmenkee71e15332015-10-07 16:39:543118 // Since the first connection couldn't be reused, need to establish another
3119 // once given credentials.
3120 MockWrite data_writes2[] = {
3121 // After calling trans->RestartWithAuth(), this is the request we should
3122 // be issuing -- the final header line contains the credentials.
3123 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173124 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543125 "Proxy-Connection: keep-alive\r\n"
3126 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3127
3128 MockWrite("GET / HTTP/1.1\r\n"
3129 "Host: www.example.org\r\n"
3130 "Connection: keep-alive\r\n\r\n"),
3131 };
3132
3133 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013134 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3135
3136 MockRead("HTTP/1.1 200 OK\r\n"),
3137 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3138 MockRead("Content-Length: 5\r\n\r\n"),
3139 MockRead(SYNCHRONOUS, "hello"),
3140 };
3141
3142 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3143 data_writes1, arraysize(data_writes1));
3144 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543145 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3146 data_writes2, arraysize(data_writes2));
3147 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013148 SSLSocketDataProvider ssl(ASYNC, OK);
3149 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3150
3151 TestCompletionCallback callback1;
3152
bnc87dcefc2017-05-25 12:47:583153 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193154 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013155
3156 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013157 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013158
3159 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013160 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463161 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013162 log.GetEntries(&entries);
3163 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003164 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3165 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013166 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003167 entries, pos,
3168 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3169 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013170
3171 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523172 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013173 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523174 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013175 EXPECT_EQ(407, response->headers->response_code());
3176 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3177 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3178
3179 LoadTimingInfo load_timing_info;
3180 // CONNECT requests and responses are handled at the connect job level, so
3181 // the transaction does not yet have a connection.
3182 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3183
3184 TestCompletionCallback callback2;
3185
3186 rv =
3187 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013188 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013189
3190 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013191 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013192
3193 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523194 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013195
3196 EXPECT_TRUE(response->headers->IsKeepAlive());
3197 EXPECT_EQ(200, response->headers->response_code());
3198 EXPECT_EQ(5, response->headers->GetContentLength());
3199 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3200
3201 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523202 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013203
3204 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3205 TestLoadTimingNotReusedWithPac(load_timing_info,
3206 CONNECT_TIMING_HAS_SSL_TIMES);
3207
3208 trans.reset();
3209 session->CloseAllConnections();
3210}
3211
3212// Test the request-challenge-retry sequence for basic auth, over a connection
3213// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013214TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593215 HttpRequestInfo request;
3216 request.method = "GET";
bncce36dca22015-04-21 22:11:233217 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593218 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293219 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103220 request.traffic_annotation =
3221 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593222
[email protected]cb9bf6ca2011-01-28 13:15:273223 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593224 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493225 ProxyResolutionService::CreateFixedFromPacResult(
3226 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513227 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073228 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273230
[email protected]394816e92010-08-03 07:38:593231 // Since we have proxy, should try to establish tunnel.
3232 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543233 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173234 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543235 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113236 };
3237
mmenkee71e15332015-10-07 16:39:543238 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083239 // connection.
3240 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543241 // No credentials.
3242 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3243 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3244 MockRead("Proxy-Connection: close\r\n\r\n"),
3245 };
mmenkee0b5c882015-08-26 20:29:113246
mmenkee71e15332015-10-07 16:39:543247 MockWrite data_writes2[] = {
3248 // After calling trans->RestartWithAuth(), this is the request we should
3249 // be issuing -- the final header line contains the credentials.
3250 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173251 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543252 "Proxy-Connection: keep-alive\r\n"
3253 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083254
mmenkee71e15332015-10-07 16:39:543255 MockWrite("GET / HTTP/1.1\r\n"
3256 "Host: www.example.org\r\n"
3257 "Connection: keep-alive\r\n\r\n"),
3258 };
3259
3260 MockRead data_reads2[] = {
3261 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3262
3263 MockRead("HTTP/1.1 200 OK\r\n"),
3264 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3265 MockRead("Content-Length: 5\r\n\r\n"),
3266 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593267 };
3268
3269 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3270 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073271 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543272 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3273 data_writes2, arraysize(data_writes2));
3274 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063275 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593277
[email protected]49639fa2011-12-20 23:22:413278 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593279
bnc87dcefc2017-05-25 12:47:583280 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193281 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503282
[email protected]49639fa2011-12-20 23:22:413283 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013284 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593285
3286 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013287 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463288 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403289 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593290 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003291 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3292 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593293 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403294 entries, pos,
mikecirone8b85c432016-09-08 19:11:003295 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3296 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593297
3298 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523299 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013300 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523301 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593302 EXPECT_EQ(407, response->headers->response_code());
3303 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043304 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593305
[email protected]029c83b62013-01-24 05:28:203306 LoadTimingInfo load_timing_info;
3307 // CONNECT requests and responses are handled at the connect job level, so
3308 // the transaction does not yet have a connection.
3309 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3310
[email protected]49639fa2011-12-20 23:22:413311 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593312
[email protected]49639fa2011-12-20 23:22:413313 rv = trans->RestartWithAuth(
3314 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593316
3317 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013318 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593319
3320 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523321 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593322
3323 EXPECT_TRUE(response->headers->IsKeepAlive());
3324 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503325 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593326 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3327
3328 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523329 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503330
[email protected]029c83b62013-01-24 05:28:203331 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3332 TestLoadTimingNotReusedWithPac(load_timing_info,
3333 CONNECT_TIMING_HAS_SSL_TIMES);
3334
[email protected]0b0bf032010-09-21 18:08:503335 trans.reset();
[email protected]102e27c2011-02-23 01:01:313336 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593337}
3338
[email protected]11203f012009-11-12 23:02:313339// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013340// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013341TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233342 // On the second pass, the body read of the auth challenge is synchronous, so
3343 // IsConnectedAndIdle returns false. The socket should still be drained and
3344 // reused. See http://crbug.com/544255.
3345 for (int i = 0; i < 2; ++i) {
3346 HttpRequestInfo request;
3347 request.method = "GET";
3348 request.url = GURL("https://www.example.org/");
3349 // Ensure that proxy authentication is attempted even
3350 // when the no authentication data flag is set.
3351 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103352 request.traffic_annotation =
3353 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013354
mmenked39192ee2015-12-09 00:57:233355 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593356 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493357 ProxyResolutionService::CreateFixed("myproxy:70",
3358 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233359 BoundTestNetLog log;
3360 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093361 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013362
bnc691fda62016-08-12 00:43:163363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013364
mmenked39192ee2015-12-09 00:57:233365 // Since we have proxy, should try to establish tunnel.
3366 MockWrite data_writes1[] = {
3367 MockWrite(ASYNC, 0,
3368 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3369 "Host: www.example.org:443\r\n"
3370 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013371
bnc691fda62016-08-12 00:43:163372 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233373 // be issuing -- the final header line contains the credentials.
3374 MockWrite(ASYNC, 3,
3375 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3376 "Host: www.example.org:443\r\n"
3377 "Proxy-Connection: keep-alive\r\n"
3378 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3379 };
ttuttle34f63b52015-03-05 04:33:013380
mmenked39192ee2015-12-09 00:57:233381 // The proxy responds to the connect with a 407, using a persistent
3382 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3383 MockRead data_reads1[] = {
3384 // No credentials.
3385 MockRead(ASYNC, 1,
3386 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3387 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3388 "Proxy-Connection: keep-alive\r\n"
3389 "Content-Length: 10\r\n\r\n"),
3390 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013391
mmenked39192ee2015-12-09 00:57:233392 // Wrong credentials (wrong password).
3393 MockRead(ASYNC, 4,
3394 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3395 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3396 "Proxy-Connection: keep-alive\r\n"
3397 "Content-Length: 10\r\n\r\n"),
3398 // No response body because the test stops reading here.
3399 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3400 };
ttuttle34f63b52015-03-05 04:33:013401
mmenked39192ee2015-12-09 00:57:233402 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3403 arraysize(data_writes1));
3404 data1.set_busy_before_sync_reads(true);
3405 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013406
mmenked39192ee2015-12-09 00:57:233407 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013408
bnc691fda62016-08-12 00:43:163409 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013410 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013411
mmenked39192ee2015-12-09 00:57:233412 TestNetLogEntry::List entries;
3413 log.GetEntries(&entries);
3414 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003415 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3416 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233417 ExpectLogContainsSomewhere(
3418 entries, pos,
mikecirone8b85c432016-09-08 19:11:003419 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3420 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013421
bnc691fda62016-08-12 00:43:163422 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233423 ASSERT_TRUE(response);
3424 ASSERT_TRUE(response->headers);
3425 EXPECT_TRUE(response->headers->IsKeepAlive());
3426 EXPECT_EQ(407, response->headers->response_code());
3427 EXPECT_EQ(10, response->headers->GetContentLength());
3428 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3429 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013430
mmenked39192ee2015-12-09 00:57:233431 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013432
mmenked39192ee2015-12-09 00:57:233433 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163434 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3435 callback2.callback());
robpercival214763f2016-07-01 23:27:013436 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013437
bnc691fda62016-08-12 00:43:163438 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233439 ASSERT_TRUE(response);
3440 ASSERT_TRUE(response->headers);
3441 EXPECT_TRUE(response->headers->IsKeepAlive());
3442 EXPECT_EQ(407, response->headers->response_code());
3443 EXPECT_EQ(10, response->headers->GetContentLength());
3444 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3445 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013446
mmenked39192ee2015-12-09 00:57:233447 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3448 // out of scope.
3449 session->CloseAllConnections();
3450 }
ttuttle34f63b52015-03-05 04:33:013451}
3452
3453// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3454// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013455TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233456 // On the second pass, the body read of the auth challenge is synchronous, so
3457 // IsConnectedAndIdle returns false. The socket should still be drained and
3458 // reused. See http://crbug.com/544255.
3459 for (int i = 0; i < 2; ++i) {
3460 HttpRequestInfo request;
3461 request.method = "GET";
3462 request.url = GURL("https://www.example.org/");
3463 // Ensure that proxy authentication is attempted even
3464 // when the no authentication data flag is set.
3465 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103466 request.traffic_annotation =
3467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233468
3469 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593470 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493471 ProxyResolutionService::CreateFixed("myproxy:70",
3472 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233473 BoundTestNetLog log;
3474 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233476
bnc691fda62016-08-12 00:43:163477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233478
3479 // Since we have proxy, should try to establish tunnel.
3480 MockWrite data_writes1[] = {
3481 MockWrite(ASYNC, 0,
3482 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3483 "Host: www.example.org:443\r\n"
3484 "Proxy-Connection: keep-alive\r\n\r\n"),
3485
bnc691fda62016-08-12 00:43:163486 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233487 // be issuing -- the final header line contains the credentials.
3488 MockWrite(ASYNC, 3,
3489 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3490 "Host: www.example.org:443\r\n"
3491 "Proxy-Connection: keep-alive\r\n"
3492 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3493 };
3494
3495 // The proxy responds to the connect with a 407, using a persistent
3496 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3497 MockRead data_reads1[] = {
3498 // No credentials.
3499 MockRead(ASYNC, 1,
3500 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3501 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3502 "Content-Length: 10\r\n\r\n"),
3503 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3504
3505 // Wrong credentials (wrong password).
3506 MockRead(ASYNC, 4,
3507 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3508 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3509 "Content-Length: 10\r\n\r\n"),
3510 // No response body because the test stops reading here.
3511 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3512 };
3513
3514 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3515 arraysize(data_writes1));
3516 data1.set_busy_before_sync_reads(true);
3517 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3518
3519 TestCompletionCallback callback1;
3520
bnc691fda62016-08-12 00:43:163521 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013522 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233523
3524 TestNetLogEntry::List entries;
3525 log.GetEntries(&entries);
3526 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003527 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3528 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233529 ExpectLogContainsSomewhere(
3530 entries, pos,
mikecirone8b85c432016-09-08 19:11:003531 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3532 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233533
bnc691fda62016-08-12 00:43:163534 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233535 ASSERT_TRUE(response);
3536 ASSERT_TRUE(response->headers);
3537 EXPECT_TRUE(response->headers->IsKeepAlive());
3538 EXPECT_EQ(407, response->headers->response_code());
3539 EXPECT_EQ(10, response->headers->GetContentLength());
3540 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3541 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3542
3543 TestCompletionCallback callback2;
3544
3545 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163546 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3547 callback2.callback());
robpercival214763f2016-07-01 23:27:013548 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233549
bnc691fda62016-08-12 00:43:163550 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233551 ASSERT_TRUE(response);
3552 ASSERT_TRUE(response->headers);
3553 EXPECT_TRUE(response->headers->IsKeepAlive());
3554 EXPECT_EQ(407, response->headers->response_code());
3555 EXPECT_EQ(10, response->headers->GetContentLength());
3556 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3557 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3558
3559 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3560 // out of scope.
3561 session->CloseAllConnections();
3562 }
3563}
3564
3565// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3566// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3567// the case the server sends extra data on the original socket, so it can't be
3568// reused.
bncd16676a2016-07-20 16:23:013569TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273570 HttpRequestInfo request;
3571 request.method = "GET";
bncce36dca22015-04-21 22:11:233572 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273573 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293574 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103575 request.traffic_annotation =
3576 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273577
[email protected]2d2697f92009-02-18 21:00:323578 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593579 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493580 ProxyResolutionService::CreateFixedFromPacResult(
3581 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513582 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073583 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323585
[email protected]2d2697f92009-02-18 21:00:323586 // Since we have proxy, should try to establish tunnel.
3587 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233588 MockWrite(ASYNC, 0,
3589 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173590 "Host: www.example.org:443\r\n"
3591 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233592 };
[email protected]2d2697f92009-02-18 21:00:323593
mmenked39192ee2015-12-09 00:57:233594 // The proxy responds to the connect with a 407, using a persistent, but sends
3595 // extra data, so the socket cannot be reused.
3596 MockRead data_reads1[] = {
3597 // No credentials.
3598 MockRead(ASYNC, 1,
3599 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3600 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3601 "Content-Length: 10\r\n\r\n"),
3602 MockRead(SYNCHRONOUS, 2, "0123456789"),
3603 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3604 };
3605
3606 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233607 // After calling trans->RestartWithAuth(), this is the request we should
3608 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233609 MockWrite(ASYNC, 0,
3610 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173611 "Host: www.example.org:443\r\n"
3612 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233613 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3614
3615 MockWrite(ASYNC, 2,
3616 "GET / HTTP/1.1\r\n"
3617 "Host: www.example.org\r\n"
3618 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323619 };
3620
mmenked39192ee2015-12-09 00:57:233621 MockRead data_reads2[] = {
3622 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323623
mmenked39192ee2015-12-09 00:57:233624 MockRead(ASYNC, 3,
3625 "HTTP/1.1 200 OK\r\n"
3626 "Content-Type: text/html; charset=iso-8859-1\r\n"
3627 "Content-Length: 5\r\n\r\n"),
3628 // No response body because the test stops reading here.
3629 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323630 };
3631
mmenked39192ee2015-12-09 00:57:233632 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3633 arraysize(data_writes1));
3634 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073635 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233636 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3637 arraysize(data_writes2));
3638 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3639 SSLSocketDataProvider ssl(ASYNC, OK);
3640 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323641
[email protected]49639fa2011-12-20 23:22:413642 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323643
bnc87dcefc2017-05-25 12:47:583644 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193645 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323646
mmenked39192ee2015-12-09 00:57:233647 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013648 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233649
mmenke43758e62015-05-04 21:09:463650 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403651 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393652 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003653 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3654 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393655 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403656 entries, pos,
mikecirone8b85c432016-09-08 19:11:003657 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3658 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323659
[email protected]1c773ea12009-04-28 19:58:423660 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243661 ASSERT_TRUE(response);
3662 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323663 EXPECT_TRUE(response->headers->IsKeepAlive());
3664 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423665 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043666 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323667
mmenked39192ee2015-12-09 00:57:233668 LoadTimingInfo load_timing_info;
3669 // CONNECT requests and responses are handled at the connect job level, so
3670 // the transaction does not yet have a connection.
3671 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3672
[email protected]49639fa2011-12-20 23:22:413673 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323674
mmenked39192ee2015-12-09 00:57:233675 rv =
3676 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013677 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323678
[email protected]2d2697f92009-02-18 21:00:323679 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233680 EXPECT_EQ(200, response->headers->response_code());
3681 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423682 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133683
mmenked39192ee2015-12-09 00:57:233684 // The password prompt info should not be set.
3685 EXPECT_FALSE(response->auth_challenge);
3686
3687 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3688 TestLoadTimingNotReusedWithPac(load_timing_info,
3689 CONNECT_TIMING_HAS_SSL_TIMES);
3690
3691 trans.reset();
[email protected]102e27c2011-02-23 01:01:313692 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323693}
3694
mmenkee71e15332015-10-07 16:39:543695// Test the case a proxy closes a socket while the challenge body is being
3696// drained.
bncd16676a2016-07-20 16:23:013697TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543698 HttpRequestInfo request;
3699 request.method = "GET";
3700 request.url = GURL("https://www.example.org/");
3701 // Ensure that proxy authentication is attempted even
3702 // when the no authentication data flag is set.
3703 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103704 request.traffic_annotation =
3705 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543706
3707 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493708 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3709 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093710 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543711
bnc691fda62016-08-12 00:43:163712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543713
3714 // Since we have proxy, should try to establish tunnel.
3715 MockWrite data_writes1[] = {
3716 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173717 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543718 "Proxy-Connection: keep-alive\r\n\r\n"),
3719 };
3720
3721 // The proxy responds to the connect with a 407, using a persistent
3722 // connection.
3723 MockRead data_reads1[] = {
3724 // No credentials.
3725 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3726 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3727 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3728 // Server hands up in the middle of the body.
3729 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3730 };
3731
3732 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163733 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543734 // be issuing -- the final header line contains the credentials.
3735 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173736 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543737 "Proxy-Connection: keep-alive\r\n"
3738 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3739
3740 MockWrite("GET / HTTP/1.1\r\n"
3741 "Host: www.example.org\r\n"
3742 "Connection: keep-alive\r\n\r\n"),
3743 };
3744
3745 MockRead data_reads2[] = {
3746 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3747
3748 MockRead("HTTP/1.1 200 OK\r\n"),
3749 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3750 MockRead("Content-Length: 5\r\n\r\n"),
3751 MockRead(SYNCHRONOUS, "hello"),
3752 };
3753
3754 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3755 data_writes1, arraysize(data_writes1));
3756 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3757 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3758 data_writes2, arraysize(data_writes2));
3759 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3760 SSLSocketDataProvider ssl(ASYNC, OK);
3761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3762
3763 TestCompletionCallback callback;
3764
tfarina42834112016-09-22 13:38:203765 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013766 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543767
bnc691fda62016-08-12 00:43:163768 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543769 ASSERT_TRUE(response);
3770 ASSERT_TRUE(response->headers);
3771 EXPECT_TRUE(response->headers->IsKeepAlive());
3772 EXPECT_EQ(407, response->headers->response_code());
3773 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3774
bnc691fda62016-08-12 00:43:163775 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013776 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543777
bnc691fda62016-08-12 00:43:163778 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543779 ASSERT_TRUE(response);
3780 ASSERT_TRUE(response->headers);
3781 EXPECT_TRUE(response->headers->IsKeepAlive());
3782 EXPECT_EQ(200, response->headers->response_code());
3783 std::string body;
bnc691fda62016-08-12 00:43:163784 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543785 EXPECT_EQ("hello", body);
3786}
3787
[email protected]a8e9b162009-03-12 00:06:443788// Test that we don't read the response body when we fail to establish a tunnel,
3789// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013790TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273791 HttpRequestInfo request;
3792 request.method = "GET";
bncce36dca22015-04-21 22:11:233793 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103794 request.traffic_annotation =
3795 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273796
[email protected]a8e9b162009-03-12 00:06:443797 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493798 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3799 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443800
danakj1fd259a02016-04-16 03:17:093801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443802
bnc691fda62016-08-12 00:43:163803 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443804
[email protected]a8e9b162009-03-12 00:06:443805 // Since we have proxy, should try to establish tunnel.
3806 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173807 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3808 "Host: www.example.org:443\r\n"
3809 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443810 };
3811
3812 // The proxy responds to the connect with a 407.
3813 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243814 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3815 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3816 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233817 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243818 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443819 };
3820
[email protected]31a2bfe2010-02-09 08:03:393821 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3822 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073823 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443824
[email protected]49639fa2011-12-20 23:22:413825 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443826
tfarina42834112016-09-22 13:38:203827 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443829
3830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013831 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443832
bnc691fda62016-08-12 00:43:163833 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243834 ASSERT_TRUE(response);
3835 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443836 EXPECT_TRUE(response->headers->IsKeepAlive());
3837 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423838 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443839
3840 std::string response_data;
bnc691fda62016-08-12 00:43:163841 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013842 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183843
3844 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313845 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443846}
3847
ttuttle7933c112015-01-06 00:55:243848// Test that we don't pass extraneous headers from the proxy's response to the
3849// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013850TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243851 HttpRequestInfo request;
3852 request.method = "GET";
bncce36dca22015-04-21 22:11:233853 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103854 request.traffic_annotation =
3855 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243856
3857 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493858 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3859 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243860
danakj1fd259a02016-04-16 03:17:093861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243862
bnc691fda62016-08-12 00:43:163863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243864
3865 // Since we have proxy, should try to establish tunnel.
3866 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173867 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3868 "Host: www.example.org:443\r\n"
3869 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243870 };
3871
3872 // The proxy responds to the connect with a 407.
3873 MockRead data_reads[] = {
3874 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3875 MockRead("X-Foo: bar\r\n"),
3876 MockRead("Set-Cookie: foo=bar\r\n"),
3877 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3878 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233879 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243880 };
3881
3882 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3883 arraysize(data_writes));
3884 session_deps_.socket_factory->AddSocketDataProvider(&data);
3885
3886 TestCompletionCallback callback;
3887
tfarina42834112016-09-22 13:38:203888 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243890
3891 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013892 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243893
bnc691fda62016-08-12 00:43:163894 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243895 ASSERT_TRUE(response);
3896 ASSERT_TRUE(response->headers);
3897 EXPECT_TRUE(response->headers->IsKeepAlive());
3898 EXPECT_EQ(407, response->headers->response_code());
3899 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3900 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3901 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3902
3903 std::string response_data;
bnc691fda62016-08-12 00:43:163904 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013905 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243906
3907 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3908 session->CloseAllConnections();
3909}
3910
[email protected]8fdbcd22010-05-05 02:54:523911// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3912// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013913TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523914 HttpRequestInfo request;
3915 request.method = "GET";
bncce36dca22015-04-21 22:11:233916 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103917 request.traffic_annotation =
3918 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523919
[email protected]cb9bf6ca2011-01-28 13:15:273920 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273923
[email protected]8fdbcd22010-05-05 02:54:523924 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233925 MockWrite(
3926 "GET / HTTP/1.1\r\n"
3927 "Host: www.example.org\r\n"
3928 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523929 };
3930
3931 MockRead data_reads1[] = {
3932 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3933 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3934 // Large content-length -- won't matter, as connection will be reset.
3935 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063936 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523937 };
3938
3939 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3940 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523942
[email protected]49639fa2011-12-20 23:22:413943 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523944
tfarina42834112016-09-22 13:38:203945 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523947
3948 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013949 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523950}
3951
[email protected]7a67a8152010-11-05 18:31:103952// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3953// through a non-authenticating proxy. The request should fail with
3954// ERR_UNEXPECTED_PROXY_AUTH.
3955// Note that it is impossible to detect if an HTTP server returns a 407 through
3956// a non-authenticating proxy - there is nothing to indicate whether the
3957// response came from the proxy or the server, so it is treated as if the proxy
3958// issued the challenge.
bncd16676a2016-07-20 16:23:013959TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273960 HttpRequestInfo request;
3961 request.method = "GET";
bncce36dca22015-04-21 22:11:233962 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103963 request.traffic_annotation =
3964 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273965
Ramin Halavatica8d5252018-03-12 05:33:493966 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3967 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513968 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073969 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093970 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103971
[email protected]7a67a8152010-11-05 18:31:103972 // Since we have proxy, should try to establish tunnel.
3973 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173974 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3975 "Host: www.example.org:443\r\n"
3976 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103977
rsleevidb16bb02015-11-12 23:47:173978 MockWrite("GET / HTTP/1.1\r\n"
3979 "Host: www.example.org\r\n"
3980 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103981 };
3982
3983 MockRead data_reads1[] = {
3984 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3985
3986 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3987 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3988 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063989 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103990 };
3991
3992 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3993 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073994 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063995 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103997
[email protected]49639fa2011-12-20 23:22:413998 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103999
bnc691fda62016-08-12 00:43:164000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104001
bnc691fda62016-08-12 00:43:164002 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104004
4005 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014006 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464007 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404008 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104009 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004010 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4011 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104012 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404013 entries, pos,
mikecirone8b85c432016-09-08 19:11:004014 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4015 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104016}
[email protected]2df19bb2010-08-25 20:13:464017
mmenke2a1781d2015-10-07 19:25:334018// Test a proxy auth scheme that allows default credentials and a proxy server
4019// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014020TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334021 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4022 HttpRequestInfo request;
4023 request.method = "GET";
4024 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104025 request.traffic_annotation =
4026 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334027
4028 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594029 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494030 ProxyResolutionService::CreateFixedFromPacResult(
4031 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334032
Jeremy Roman0579ed62017-08-29 15:56:194033 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334034 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194035 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334036 mock_handler->set_allows_default_credentials(true);
4037 auth_handler_factory->AddMockHandler(mock_handler.release(),
4038 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484039 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334040
4041 // Add NetLog just so can verify load timing information gets a NetLog ID.
4042 NetLog net_log;
4043 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094044 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334045
4046 // Since we have proxy, should try to establish tunnel.
4047 MockWrite data_writes1[] = {
4048 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174049 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334050 "Proxy-Connection: keep-alive\r\n\r\n"),
4051 };
4052
4053 // The proxy responds to the connect with a 407, using a non-persistent
4054 // connection.
4055 MockRead data_reads1[] = {
4056 // No credentials.
4057 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4058 MockRead("Proxy-Authenticate: Mock\r\n"),
4059 MockRead("Proxy-Connection: close\r\n\r\n"),
4060 };
4061
4062 // Since the first connection couldn't be reused, need to establish another
4063 // once given credentials.
4064 MockWrite data_writes2[] = {
4065 // After calling trans->RestartWithAuth(), this is the request we should
4066 // be issuing -- the final header line contains the credentials.
4067 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174068 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334069 "Proxy-Connection: keep-alive\r\n"
4070 "Proxy-Authorization: auth_token\r\n\r\n"),
4071
4072 MockWrite("GET / HTTP/1.1\r\n"
4073 "Host: www.example.org\r\n"
4074 "Connection: keep-alive\r\n\r\n"),
4075 };
4076
4077 MockRead data_reads2[] = {
4078 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4079
4080 MockRead("HTTP/1.1 200 OK\r\n"),
4081 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4082 MockRead("Content-Length: 5\r\n\r\n"),
4083 MockRead(SYNCHRONOUS, "hello"),
4084 };
4085
4086 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4087 data_writes1, arraysize(data_writes1));
4088 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4089 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4090 data_writes2, arraysize(data_writes2));
4091 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4092 SSLSocketDataProvider ssl(ASYNC, OK);
4093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4094
bnc87dcefc2017-05-25 12:47:584095 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194096 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334097
4098 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204099 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014100 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334101
4102 const HttpResponseInfo* response = trans->GetResponseInfo();
4103 ASSERT_TRUE(response);
4104 ASSERT_TRUE(response->headers);
4105 EXPECT_FALSE(response->headers->IsKeepAlive());
4106 EXPECT_EQ(407, response->headers->response_code());
4107 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4108 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524109 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334110
4111 LoadTimingInfo load_timing_info;
4112 // CONNECT requests and responses are handled at the connect job level, so
4113 // the transaction does not yet have a connection.
4114 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4115
4116 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014117 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334118 response = trans->GetResponseInfo();
4119 ASSERT_TRUE(response);
4120 ASSERT_TRUE(response->headers);
4121 EXPECT_TRUE(response->headers->IsKeepAlive());
4122 EXPECT_EQ(200, response->headers->response_code());
4123 EXPECT_EQ(5, response->headers->GetContentLength());
4124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4125
4126 // The password prompt info should not be set.
4127 EXPECT_FALSE(response->auth_challenge);
4128
4129 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4130 TestLoadTimingNotReusedWithPac(load_timing_info,
4131 CONNECT_TIMING_HAS_SSL_TIMES);
4132
4133 trans.reset();
4134 session->CloseAllConnections();
4135}
4136
4137// Test a proxy auth scheme that allows default credentials and a proxy server
4138// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014139TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334140 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4141 HttpRequestInfo request;
4142 request.method = "GET";
4143 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104144 request.traffic_annotation =
4145 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334146
4147 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594148 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494149 ProxyResolutionService::CreateFixedFromPacResult(
4150 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334151
Jeremy Roman0579ed62017-08-29 15:56:194152 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334153 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194154 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334155 mock_handler->set_allows_default_credentials(true);
4156 auth_handler_factory->AddMockHandler(mock_handler.release(),
4157 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484158 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334159
4160 // Add NetLog just so can verify load timing information gets a NetLog ID.
4161 NetLog net_log;
4162 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094163 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334164
4165 // Should try to establish tunnel.
4166 MockWrite data_writes1[] = {
4167 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174168 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334169 "Proxy-Connection: keep-alive\r\n\r\n"),
4170
4171 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174172 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334173 "Proxy-Connection: keep-alive\r\n"
4174 "Proxy-Authorization: auth_token\r\n\r\n"),
4175 };
4176
4177 // The proxy responds to the connect with a 407, using a non-persistent
4178 // connection.
4179 MockRead data_reads1[] = {
4180 // No credentials.
4181 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4182 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4183 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4184 };
4185
4186 // Since the first connection was closed, need to establish another once given
4187 // credentials.
4188 MockWrite data_writes2[] = {
4189 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174190 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334191 "Proxy-Connection: keep-alive\r\n"
4192 "Proxy-Authorization: auth_token\r\n\r\n"),
4193
4194 MockWrite("GET / HTTP/1.1\r\n"
4195 "Host: www.example.org\r\n"
4196 "Connection: keep-alive\r\n\r\n"),
4197 };
4198
4199 MockRead data_reads2[] = {
4200 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4201
4202 MockRead("HTTP/1.1 200 OK\r\n"),
4203 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4204 MockRead("Content-Length: 5\r\n\r\n"),
4205 MockRead(SYNCHRONOUS, "hello"),
4206 };
4207
4208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4209 data_writes1, arraysize(data_writes1));
4210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4211 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4212 data_writes2, arraysize(data_writes2));
4213 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4214 SSLSocketDataProvider ssl(ASYNC, OK);
4215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4216
bnc87dcefc2017-05-25 12:47:584217 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194218 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334219
4220 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204221 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014222 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334223
4224 const HttpResponseInfo* response = trans->GetResponseInfo();
4225 ASSERT_TRUE(response);
4226 ASSERT_TRUE(response->headers);
4227 EXPECT_TRUE(response->headers->IsKeepAlive());
4228 EXPECT_EQ(407, response->headers->response_code());
4229 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4230 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4231 EXPECT_FALSE(response->auth_challenge);
4232
4233 LoadTimingInfo load_timing_info;
4234 // CONNECT requests and responses are handled at the connect job level, so
4235 // the transaction does not yet have a connection.
4236 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4237
4238 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014239 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334240
4241 response = trans->GetResponseInfo();
4242 ASSERT_TRUE(response);
4243 ASSERT_TRUE(response->headers);
4244 EXPECT_TRUE(response->headers->IsKeepAlive());
4245 EXPECT_EQ(200, response->headers->response_code());
4246 EXPECT_EQ(5, response->headers->GetContentLength());
4247 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4248
4249 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524250 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334251
4252 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4253 TestLoadTimingNotReusedWithPac(load_timing_info,
4254 CONNECT_TIMING_HAS_SSL_TIMES);
4255
4256 trans.reset();
4257 session->CloseAllConnections();
4258}
4259
4260// Test a proxy auth scheme that allows default credentials and a proxy server
4261// that hangs up when credentials are initially sent, and hangs up again when
4262// they are retried.
bncd16676a2016-07-20 16:23:014263TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334264 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4265 HttpRequestInfo request;
4266 request.method = "GET";
4267 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104268 request.traffic_annotation =
4269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334270
4271 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594272 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494273 ProxyResolutionService::CreateFixedFromPacResult(
4274 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334275
Jeremy Roman0579ed62017-08-29 15:56:194276 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334277 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194278 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334279 mock_handler->set_allows_default_credentials(true);
4280 auth_handler_factory->AddMockHandler(mock_handler.release(),
4281 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484282 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334283
4284 // Add NetLog just so can verify load timing information gets a NetLog ID.
4285 NetLog net_log;
4286 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094287 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334288
4289 // Should try to establish tunnel.
4290 MockWrite data_writes1[] = {
4291 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174292 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334293 "Proxy-Connection: keep-alive\r\n\r\n"),
4294
4295 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174296 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334297 "Proxy-Connection: keep-alive\r\n"
4298 "Proxy-Authorization: auth_token\r\n\r\n"),
4299 };
4300
4301 // The proxy responds to the connect with a 407, and then hangs up after the
4302 // second request is sent.
4303 MockRead data_reads1[] = {
4304 // No credentials.
4305 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4306 MockRead("Content-Length: 0\r\n"),
4307 MockRead("Proxy-Connection: keep-alive\r\n"),
4308 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4309 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4310 };
4311
4312 // HttpNetworkTransaction sees a reused connection that was closed with
4313 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4314 // request.
4315 MockWrite data_writes2[] = {
4316 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174317 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334318 "Proxy-Connection: keep-alive\r\n\r\n"),
4319 };
4320
4321 // The proxy, having had more than enough of us, just hangs up.
4322 MockRead data_reads2[] = {
4323 // No credentials.
4324 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4325 };
4326
4327 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4328 data_writes1, arraysize(data_writes1));
4329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4330 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4331 data_writes2, arraysize(data_writes2));
4332 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4333
bnc87dcefc2017-05-25 12:47:584334 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194335 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334336
4337 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204338 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014339 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334340
4341 const HttpResponseInfo* response = trans->GetResponseInfo();
4342 ASSERT_TRUE(response);
4343 ASSERT_TRUE(response->headers);
4344 EXPECT_TRUE(response->headers->IsKeepAlive());
4345 EXPECT_EQ(407, response->headers->response_code());
4346 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4347 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4348 EXPECT_FALSE(response->auth_challenge);
4349
4350 LoadTimingInfo load_timing_info;
4351 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4352
4353 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014354 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334355
4356 trans.reset();
4357 session->CloseAllConnections();
4358}
4359
4360// Test a proxy auth scheme that allows default credentials and a proxy server
4361// that hangs up when credentials are initially sent, and sends a challenge
4362// again they are retried.
bncd16676a2016-07-20 16:23:014363TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334364 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4365 HttpRequestInfo request;
4366 request.method = "GET";
4367 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104368 request.traffic_annotation =
4369 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334370
4371 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594372 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494373 ProxyResolutionService::CreateFixedFromPacResult(
4374 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334375
Jeremy Roman0579ed62017-08-29 15:56:194376 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334377 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194378 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334379 mock_handler->set_allows_default_credentials(true);
4380 auth_handler_factory->AddMockHandler(mock_handler.release(),
4381 HttpAuth::AUTH_PROXY);
4382 // Add another handler for the second challenge. It supports default
4383 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194384 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334385 mock_handler->set_allows_default_credentials(true);
4386 auth_handler_factory->AddMockHandler(mock_handler.release(),
4387 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484388 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334389
4390 // Add NetLog just so can verify load timing information gets a NetLog ID.
4391 NetLog net_log;
4392 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094393 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334394
4395 // Should try to establish tunnel.
4396 MockWrite data_writes1[] = {
4397 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174398 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334399 "Proxy-Connection: keep-alive\r\n\r\n"),
4400 };
4401
4402 // The proxy responds to the connect with a 407, using a non-persistent
4403 // connection.
4404 MockRead data_reads1[] = {
4405 // No credentials.
4406 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4407 MockRead("Proxy-Authenticate: Mock\r\n"),
4408 MockRead("Proxy-Connection: close\r\n\r\n"),
4409 };
4410
4411 // Since the first connection was closed, need to establish another once given
4412 // credentials.
4413 MockWrite data_writes2[] = {
4414 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174415 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334416 "Proxy-Connection: keep-alive\r\n"
4417 "Proxy-Authorization: auth_token\r\n\r\n"),
4418 };
4419
4420 MockRead data_reads2[] = {
4421 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4422 MockRead("Proxy-Authenticate: Mock\r\n"),
4423 MockRead("Proxy-Connection: close\r\n\r\n"),
4424 };
4425
4426 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4427 data_writes1, arraysize(data_writes1));
4428 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4429 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4430 data_writes2, arraysize(data_writes2));
4431 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4432 SSLSocketDataProvider ssl(ASYNC, OK);
4433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4434
bnc87dcefc2017-05-25 12:47:584435 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194436 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334437
4438 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204439 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014440 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334441
4442 const HttpResponseInfo* response = trans->GetResponseInfo();
4443 ASSERT_TRUE(response);
4444 ASSERT_TRUE(response->headers);
4445 EXPECT_EQ(407, response->headers->response_code());
4446 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4447 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4448 EXPECT_FALSE(response->auth_challenge);
4449
4450 LoadTimingInfo load_timing_info;
4451 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4452
4453 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014454 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334455 response = trans->GetResponseInfo();
4456 ASSERT_TRUE(response);
4457 ASSERT_TRUE(response->headers);
4458 EXPECT_EQ(407, response->headers->response_code());
4459 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4460 EXPECT_TRUE(response->auth_challenge);
4461
4462 trans.reset();
4463 session->CloseAllConnections();
4464}
4465
asankae2257db2016-10-11 22:03:164466// A more nuanced test than GenerateAuthToken test which asserts that
4467// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4468// unnecessarily invalidated, and that if the server co-operates, the
4469// authentication handshake can continue with the same scheme but with a
4470// different identity.
4471TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4472 HttpRequestInfo request;
4473 request.method = "GET";
4474 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104475 request.traffic_annotation =
4476 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164477
Jeremy Roman0579ed62017-08-29 15:56:194478 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164479 auth_handler_factory->set_do_init_from_challenge(true);
4480
4481 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194482 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164483 mock_handler->set_allows_default_credentials(true);
4484 mock_handler->set_allows_explicit_credentials(true);
4485 mock_handler->set_connection_based(true);
4486 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4487 auth_handler_factory->AddMockHandler(mock_handler.release(),
4488 HttpAuth::AUTH_SERVER);
4489
4490 // Add another handler for the second challenge. It supports default
4491 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194492 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164493 mock_handler->set_allows_default_credentials(true);
4494 mock_handler->set_allows_explicit_credentials(true);
4495 mock_handler->set_connection_based(true);
4496 auth_handler_factory->AddMockHandler(mock_handler.release(),
4497 HttpAuth::AUTH_SERVER);
4498 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4499
4500 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4501
4502 MockWrite data_writes1[] = {
4503 MockWrite("GET / HTTP/1.1\r\n"
4504 "Host: www.example.org\r\n"
4505 "Connection: keep-alive\r\n\r\n"),
4506 };
4507
4508 MockRead data_reads1[] = {
4509 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4510 "WWW-Authenticate: Mock\r\n"
4511 "Connection: keep-alive\r\n\r\n"),
4512 };
4513
4514 // Identical to data_writes1[]. The AuthHandler encounters a
4515 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4516 // transaction procceds without an authorization header.
4517 MockWrite data_writes2[] = {
4518 MockWrite("GET / HTTP/1.1\r\n"
4519 "Host: www.example.org\r\n"
4520 "Connection: keep-alive\r\n\r\n"),
4521 };
4522
4523 MockRead data_reads2[] = {
4524 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4525 "WWW-Authenticate: Mock\r\n"
4526 "Connection: keep-alive\r\n\r\n"),
4527 };
4528
4529 MockWrite data_writes3[] = {
4530 MockWrite("GET / HTTP/1.1\r\n"
4531 "Host: www.example.org\r\n"
4532 "Connection: keep-alive\r\n"
4533 "Authorization: auth_token\r\n\r\n"),
4534 };
4535
4536 MockRead data_reads3[] = {
4537 MockRead("HTTP/1.1 200 OK\r\n"
4538 "Content-Length: 5\r\n"
4539 "Content-Type: text/plain\r\n"
4540 "Connection: keep-alive\r\n\r\n"
4541 "Hello"),
4542 };
4543
4544 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4545 data_writes1, arraysize(data_writes1));
4546 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4547
4548 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4549 data_writes2, arraysize(data_writes2));
4550 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4551
4552 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4553 data_writes3, arraysize(data_writes3));
4554 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4555
bnc87dcefc2017-05-25 12:47:584556 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194557 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164558
4559 TestCompletionCallback callback;
4560 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4561 EXPECT_THAT(callback.GetResult(rv), IsOk());
4562
4563 const HttpResponseInfo* response = trans->GetResponseInfo();
4564 ASSERT_TRUE(response);
4565 ASSERT_TRUE(response->headers);
4566 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4567
4568 // The following three tests assert that an authentication challenge was
4569 // received and that the stack is ready to respond to the challenge using
4570 // ambient credentials.
4571 EXPECT_EQ(401, response->headers->response_code());
4572 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4573 EXPECT_FALSE(response->auth_challenge);
4574
4575 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4576 EXPECT_THAT(callback.GetResult(rv), IsOk());
4577 response = trans->GetResponseInfo();
4578 ASSERT_TRUE(response);
4579 ASSERT_TRUE(response->headers);
4580
4581 // The following three tests assert that an authentication challenge was
4582 // received and that the stack needs explicit credentials before it is ready
4583 // to respond to the challenge.
4584 EXPECT_EQ(401, response->headers->response_code());
4585 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4586 EXPECT_TRUE(response->auth_challenge);
4587
4588 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4589 EXPECT_THAT(callback.GetResult(rv), IsOk());
4590 response = trans->GetResponseInfo();
4591 ASSERT_TRUE(response);
4592 ASSERT_TRUE(response->headers);
4593 EXPECT_EQ(200, response->headers->response_code());
4594
4595 trans.reset();
4596 session->CloseAllConnections();
4597}
4598
Matt Menked1eb6d42018-01-17 04:54:064599// Proxy resolver that returns a proxy with the same host and port for different
4600// schemes, based on the path of the URL being requests.
4601class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4602 public:
4603 SameProxyWithDifferentSchemesProxyResolver() {}
4604 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4605
4606 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4607
4608 static HostPortPair ProxyHostPortPair() {
4609 return HostPortPair::FromString(ProxyHostPortPairAsString());
4610 }
4611
4612 // ProxyResolver implementation.
4613 int GetProxyForURL(const GURL& url,
4614 ProxyInfo* results,
4615 const CompletionCallback& callback,
4616 std::unique_ptr<Request>* request,
4617 const NetLogWithSource& /*net_log*/) override {
4618 *results = ProxyInfo();
4619 if (url.path() == "/socks4") {
4620 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4621 return OK;
4622 }
4623 if (url.path() == "/socks5") {
4624 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4625 return OK;
4626 }
4627 if (url.path() == "/http") {
4628 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4629 return OK;
4630 }
4631 if (url.path() == "/https") {
4632 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4633 return OK;
4634 }
4635 NOTREACHED();
4636 return ERR_NOT_IMPLEMENTED;
4637 }
4638
4639 private:
4640 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4641};
4642
4643class SameProxyWithDifferentSchemesProxyResolverFactory
4644 : public ProxyResolverFactory {
4645 public:
4646 SameProxyWithDifferentSchemesProxyResolverFactory()
4647 : ProxyResolverFactory(false) {}
4648
Lily Houghton99597862018-03-07 16:40:424649 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4650 std::unique_ptr<ProxyResolver>* resolver,
4651 const CompletionCallback& callback,
4652 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064653 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4654 return OK;
4655 }
4656
4657 private:
4658 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4659};
4660
4661// Check that when different proxy schemes are all applied to a proxy at the
4662// same address, the sonnections are not grouped together. i.e., a request to
4663// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4664// request to foo.com using proxy.com as an HTTP proxy.
4665TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494666 session_deps_.proxy_resolution_service =
4667 std::make_unique<ProxyResolutionService>(
4668 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4669 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4670 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4671 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064672
4673 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4674
4675 MockWrite socks_writes[] = {
4676 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4677 kSOCKS4OkRequestLocalHostPort80Length),
4678 MockWrite(SYNCHRONOUS,
4679 "GET /socks4 HTTP/1.1\r\n"
4680 "Host: test\r\n"
4681 "Connection: keep-alive\r\n\r\n"),
4682 };
4683 MockRead socks_reads[] = {
4684 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4685 MockRead("HTTP/1.0 200 OK\r\n"
4686 "Connection: keep-alive\r\n"
4687 "Content-Length: 15\r\n\r\n"
4688 "SOCKS4 Response"),
4689 };
4690 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4691 socks_writes, arraysize(socks_writes));
4692 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4693
4694 const char kSOCKS5Request[] = {
4695 0x05, // Version
4696 0x01, // Command (CONNECT)
4697 0x00, // Reserved
4698 0x03, // Address type (DOMAINNAME)
4699 0x04, // Length of domain (4)
4700 't', 'e', 's', 't', // Domain string
4701 0x00, 0x50, // 16-bit port (80)
4702 };
4703 MockWrite socks5_writes[] = {
4704 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4705 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4706 MockWrite(SYNCHRONOUS,
4707 "GET /socks5 HTTP/1.1\r\n"
4708 "Host: test\r\n"
4709 "Connection: keep-alive\r\n\r\n"),
4710 };
4711 MockRead socks5_reads[] = {
4712 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4713 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4714 MockRead("HTTP/1.0 200 OK\r\n"
4715 "Connection: keep-alive\r\n"
4716 "Content-Length: 15\r\n\r\n"
4717 "SOCKS5 Response"),
4718 };
4719 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4720 socks5_writes, arraysize(socks5_writes));
4721 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4722
4723 MockWrite http_writes[] = {
4724 MockWrite(SYNCHRONOUS,
4725 "GET http://test/http HTTP/1.1\r\n"
4726 "Host: test\r\n"
4727 "Proxy-Connection: keep-alive\r\n\r\n"),
4728 };
4729 MockRead http_reads[] = {
4730 MockRead("HTTP/1.1 200 OK\r\n"
4731 "Proxy-Connection: keep-alive\r\n"
4732 "Content-Length: 13\r\n\r\n"
4733 "HTTP Response"),
4734 };
4735 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4736 http_writes, arraysize(http_writes));
4737 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4738
4739 MockWrite https_writes[] = {
4740 MockWrite(SYNCHRONOUS,
4741 "GET http://test/https HTTP/1.1\r\n"
4742 "Host: test\r\n"
4743 "Proxy-Connection: keep-alive\r\n\r\n"),
4744 };
4745 MockRead https_reads[] = {
4746 MockRead("HTTP/1.1 200 OK\r\n"
4747 "Proxy-Connection: keep-alive\r\n"
4748 "Content-Length: 14\r\n\r\n"
4749 "HTTPS Response"),
4750 };
4751 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4752 https_writes, arraysize(https_writes));
4753 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4754 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4756
4757 struct TestCase {
4758 GURL url;
4759 std::string expected_response;
4760 // How many idle sockets there should be in the SOCKS proxy socket pool
4761 // after the test.
4762 int expected_idle_socks_sockets;
4763 // How many idle sockets there should be in the HTTP proxy socket pool after
4764 // the test.
4765 int expected_idle_http_sockets;
4766 } const kTestCases[] = {
4767 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4768 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4769 {GURL("http://test/http"), "HTTP Response", 2, 1},
4770 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4771 };
4772
4773 for (const auto& test_case : kTestCases) {
4774 HttpRequestInfo request;
4775 request.method = "GET";
4776 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:104777 request.traffic_annotation =
4778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064779 std::unique_ptr<HttpNetworkTransaction> trans =
4780 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4781 session.get());
4782 TestCompletionCallback callback;
4783 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4784 EXPECT_THAT(callback.GetResult(rv), IsOk());
4785
4786 const HttpResponseInfo* response = trans->GetResponseInfo();
4787 ASSERT_TRUE(response);
4788 ASSERT_TRUE(response->headers);
4789 EXPECT_EQ(200, response->headers->response_code());
4790 std::string response_data;
4791 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4792 EXPECT_EQ(test_case.expected_response, response_data);
4793
4794 // Return the socket to the socket pool, so can make sure it's not used for
4795 // the next requests.
4796 trans.reset();
4797 base::RunLoop().RunUntilIdle();
4798
4799 // Check the number of idle sockets in the pool, to make sure that used
4800 // sockets are indeed being returned to the socket pool. If each request
4801 // doesn't return an idle socket to the pool, the test would incorrectly
4802 // pass.
4803 EXPECT_EQ(
4804 test_case.expected_idle_socks_sockets,
4805 session
4806 ->GetSocketPoolForSOCKSProxy(
4807 HttpNetworkSession::NORMAL_SOCKET_POOL,
4808 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4809 ->IdleSocketCount());
4810 EXPECT_EQ(
4811 test_case.expected_idle_http_sockets,
4812 session
4813 ->GetSocketPoolForHTTPProxy(
4814 HttpNetworkSession::NORMAL_SOCKET_POOL,
4815 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4816 ->IdleSocketCount());
4817 }
4818}
4819
[email protected]029c83b62013-01-24 05:28:204820// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014821TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204822 HttpRequestInfo request1;
4823 request1.method = "GET";
bncce36dca22015-04-21 22:11:234824 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104825 request1.traffic_annotation =
4826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204827
4828 HttpRequestInfo request2;
4829 request2.method = "GET";
bncce36dca22015-04-21 22:11:234830 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104831 request2.traffic_annotation =
4832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204833
4834 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494835 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4836 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514837 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074838 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204840
4841 // Since we have proxy, should try to establish tunnel.
4842 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174843 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4844 "Host: www.example.org:443\r\n"
4845 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204846
rsleevidb16bb02015-11-12 23:47:174847 MockWrite("GET /1 HTTP/1.1\r\n"
4848 "Host: www.example.org\r\n"
4849 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204850
rsleevidb16bb02015-11-12 23:47:174851 MockWrite("GET /2 HTTP/1.1\r\n"
4852 "Host: www.example.org\r\n"
4853 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204854 };
4855
4856 // The proxy responds to the connect with a 407, using a persistent
4857 // connection.
4858 MockRead data_reads1[] = {
4859 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4860
4861 MockRead("HTTP/1.1 200 OK\r\n"),
4862 MockRead("Content-Length: 1\r\n\r\n"),
4863 MockRead(SYNCHRONOUS, "1"),
4864
4865 MockRead("HTTP/1.1 200 OK\r\n"),
4866 MockRead("Content-Length: 2\r\n\r\n"),
4867 MockRead(SYNCHRONOUS, "22"),
4868 };
4869
4870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4871 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204873 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204875
4876 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584877 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204879
4880 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204882
4883 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014884 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204885
4886 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524887 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474888 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524889 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204890 EXPECT_EQ(1, response1->headers->GetContentLength());
4891
4892 LoadTimingInfo load_timing_info1;
4893 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4894 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4895
4896 trans1.reset();
4897
4898 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584899 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194900 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204901
4902 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204904
4905 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014906 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204907
4908 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524909 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474910 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524911 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204912 EXPECT_EQ(2, response2->headers->GetContentLength());
4913
4914 LoadTimingInfo load_timing_info2;
4915 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4916 TestLoadTimingReused(load_timing_info2);
4917
4918 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4919
4920 trans2.reset();
4921 session->CloseAllConnections();
4922}
4923
4924// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014925TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204926 HttpRequestInfo request1;
4927 request1.method = "GET";
bncce36dca22015-04-21 22:11:234928 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104929 request1.traffic_annotation =
4930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204931
4932 HttpRequestInfo request2;
4933 request2.method = "GET";
bncce36dca22015-04-21 22:11:234934 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104935 request2.traffic_annotation =
4936 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204937
4938 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594939 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494940 ProxyResolutionService::CreateFixedFromPacResult(
4941 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514942 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074943 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204945
4946 // Since we have proxy, should try to establish tunnel.
4947 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174948 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4949 "Host: www.example.org:443\r\n"
4950 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204951
rsleevidb16bb02015-11-12 23:47:174952 MockWrite("GET /1 HTTP/1.1\r\n"
4953 "Host: www.example.org\r\n"
4954 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204955
rsleevidb16bb02015-11-12 23:47:174956 MockWrite("GET /2 HTTP/1.1\r\n"
4957 "Host: www.example.org\r\n"
4958 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204959 };
4960
4961 // The proxy responds to the connect with a 407, using a persistent
4962 // connection.
4963 MockRead data_reads1[] = {
4964 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4965
4966 MockRead("HTTP/1.1 200 OK\r\n"),
4967 MockRead("Content-Length: 1\r\n\r\n"),
4968 MockRead(SYNCHRONOUS, "1"),
4969
4970 MockRead("HTTP/1.1 200 OK\r\n"),
4971 MockRead("Content-Length: 2\r\n\r\n"),
4972 MockRead(SYNCHRONOUS, "22"),
4973 };
4974
4975 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4976 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074977 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204978 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074979 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204980
4981 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584982 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194983 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204984
4985 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204987
4988 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014989 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204990
4991 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524992 ASSERT_TRUE(response1);
4993 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204994 EXPECT_EQ(1, response1->headers->GetContentLength());
4995
4996 LoadTimingInfo load_timing_info1;
4997 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4998 TestLoadTimingNotReusedWithPac(load_timing_info1,
4999 CONNECT_TIMING_HAS_SSL_TIMES);
5000
5001 trans1.reset();
5002
5003 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585004 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195005 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205006
5007 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205009
5010 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015011 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205012
5013 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525014 ASSERT_TRUE(response2);
5015 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205016 EXPECT_EQ(2, response2->headers->GetContentLength());
5017
5018 LoadTimingInfo load_timing_info2;
5019 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5020 TestLoadTimingReusedWithPac(load_timing_info2);
5021
5022 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5023
5024 trans2.reset();
5025 session->CloseAllConnections();
5026}
5027
[email protected]2df19bb2010-08-25 20:13:465028// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015029TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275030 HttpRequestInfo request;
5031 request.method = "GET";
bncce36dca22015-04-21 22:11:235032 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105033 request.traffic_annotation =
5034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275035
[email protected]2df19bb2010-08-25 20:13:465036 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495037 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5038 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515039 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075040 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465042
[email protected]2df19bb2010-08-25 20:13:465043 // Since we have proxy, should use full url
5044 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235045 MockWrite(
5046 "GET http://www.example.org/ HTTP/1.1\r\n"
5047 "Host: www.example.org\r\n"
5048 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465049 };
5050
5051 MockRead data_reads1[] = {
5052 MockRead("HTTP/1.1 200 OK\r\n"),
5053 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5054 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065055 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465056 };
5057
5058 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5059 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065061 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465063
[email protected]49639fa2011-12-20 23:22:415064 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465065
bnc691fda62016-08-12 00:43:165066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505067
bnc691fda62016-08-12 00:43:165068 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465070
5071 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015072 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465073
[email protected]58e32bb2013-01-21 18:23:255074 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165075 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255076 TestLoadTimingNotReused(load_timing_info,
5077 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5078
bnc691fda62016-08-12 00:43:165079 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525080 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465081
tbansal2ecbbc72016-10-06 17:15:475082 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465083 EXPECT_TRUE(response->headers->IsKeepAlive());
5084 EXPECT_EQ(200, response->headers->response_code());
5085 EXPECT_EQ(100, response->headers->GetContentLength());
5086 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5087
5088 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525089 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465090}
5091
[email protected]7642b5ae2010-09-01 20:55:175092// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015093TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275094 HttpRequestInfo request;
5095 request.method = "GET";
bncce36dca22015-04-21 22:11:235096 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105097 request.traffic_annotation =
5098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275099
[email protected]7642b5ae2010-09-01 20:55:175100 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495101 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5102 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515103 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075104 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175106
bncce36dca22015-04-21 22:11:235107 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415108 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455109 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415110 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175111
bnc42331402016-07-25 13:36:155112 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415113 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175114 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415115 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175116 };
5117
rch8e6c6c42015-05-01 14:05:135118 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5119 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075120 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175121
[email protected]8ddf8322012-02-23 18:08:065122 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365123 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175125
[email protected]49639fa2011-12-20 23:22:415126 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175127
bnc691fda62016-08-12 00:43:165128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505129
bnc691fda62016-08-12 00:43:165130 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175132
5133 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015134 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175135
[email protected]58e32bb2013-01-21 18:23:255136 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165137 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255138 TestLoadTimingNotReused(load_timing_info,
5139 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5140
bnc691fda62016-08-12 00:43:165141 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525142 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475143 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525144 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025145 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175146
5147 std::string response_data;
bnc691fda62016-08-12 00:43:165148 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235149 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175150}
5151
[email protected]1c173852014-06-19 12:51:505152// Verifies that a session which races and wins against the owning transaction
5153// (completing prior to host resolution), doesn't fail the transaction.
5154// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015155TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505156 HttpRequestInfo request;
5157 request.method = "GET";
bncce36dca22015-04-21 22:11:235158 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105159 request.traffic_annotation =
5160 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505161
5162 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495163 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5164 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515165 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505166 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505168
bncce36dca22015-04-21 22:11:235169 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415170 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455171 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415172 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505173
bnc42331402016-07-25 13:36:155174 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415175 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505176 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415177 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505178 };
5179
rch8e6c6c42015-05-01 14:05:135180 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5181 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505182 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5183
5184 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365185 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5187
5188 TestCompletionCallback callback1;
5189
bnc691fda62016-08-12 00:43:165190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505191
5192 // Stall the hostname resolution begun by the transaction.
5193 session_deps_.host_resolver->set_synchronous_mode(false);
5194 session_deps_.host_resolver->set_ondemand_mode(true);
5195
bnc691fda62016-08-12 00:43:165196 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505198
5199 // Race a session to the proxy, which completes first.
5200 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045201 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5202 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505203 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525204 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505205
5206 // Unstall the resolution begun by the transaction.
5207 session_deps_.host_resolver->set_ondemand_mode(true);
5208 session_deps_.host_resolver->ResolveAllPending();
5209
5210 EXPECT_FALSE(callback1.have_result());
5211 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015212 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505213
bnc691fda62016-08-12 00:43:165214 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525215 ASSERT_TRUE(response);
5216 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025217 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505218
5219 std::string response_data;
bnc691fda62016-08-12 00:43:165220 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505221 EXPECT_EQ(kUploadData, response_data);
5222}
5223
[email protected]dc7bd1c52010-11-12 00:01:135224// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015225TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275226 HttpRequestInfo request;
5227 request.method = "GET";
bncce36dca22015-04-21 22:11:235228 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105229 request.traffic_annotation =
5230 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275231
[email protected]79cb5c12011-09-12 13:12:045232 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495233 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5234 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515235 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075236 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135238
[email protected]dc7bd1c52010-11-12 00:01:135239 // The first request will be a bare GET, the second request will be a
5240 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455241 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415242 SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485243 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385244 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135245 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465246 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135247 };
bncdf80d44fd2016-07-15 20:27:415248 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5249 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485250 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135251 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415252 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135253 };
5254
5255 // The first response is a 407 proxy authentication challenge, and the second
5256 // response will be a 200 response since the second request includes a valid
5257 // Authorization header.
5258 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465259 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135260 };
bnc42331402016-07-25 13:36:155261 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235262 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415263 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5264 SpdySerializedFrame body_authentication(
5265 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155266 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415267 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135268 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415269 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465270 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415271 CreateMockRead(resp_data, 4),
5272 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135273 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135274 };
5275
rch8e6c6c42015-05-01 14:05:135276 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5277 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075278 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135279
[email protected]8ddf8322012-02-23 18:08:065280 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365281 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135283
[email protected]49639fa2011-12-20 23:22:415284 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135285
bnc691fda62016-08-12 00:43:165286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135287
bnc691fda62016-08-12 00:43:165288 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135290
5291 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015292 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135293
bnc691fda62016-08-12 00:43:165294 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135295
wezca1070932016-05-26 20:30:525296 ASSERT_TRUE(response);
5297 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135298 EXPECT_EQ(407, response->headers->response_code());
5299 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435300 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135301
[email protected]49639fa2011-12-20 23:22:415302 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135303
bnc691fda62016-08-12 00:43:165304 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135306
5307 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015308 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135309
bnc691fda62016-08-12 00:43:165310 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135311
wezca1070932016-05-26 20:30:525312 ASSERT_TRUE(response_restart);
5313 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135314 EXPECT_EQ(200, response_restart->headers->response_code());
5315 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525316 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135317}
5318
[email protected]d9da5fe2010-10-13 22:37:165319// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015320TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275321 HttpRequestInfo request;
5322 request.method = "GET";
bncce36dca22015-04-21 22:11:235323 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105324 request.traffic_annotation =
5325 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275326
[email protected]d9da5fe2010-10-13 22:37:165327 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495328 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5329 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515330 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075331 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165333
bnc691fda62016-08-12 00:43:165334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165335
bncce36dca22015-04-21 22:11:235336 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415337 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235338 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5339 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165340
bncce36dca22015-04-21 22:11:235341 const char get[] =
5342 "GET / HTTP/1.1\r\n"
5343 "Host: www.example.org\r\n"
5344 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415345 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195346 spdy_util_.ConstructSpdyDataFrame(1, get, false));
bnc42331402016-07-25 13:36:155347 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165348 const char resp[] = "HTTP/1.1 200 OK\r\n"
5349 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415350 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195351 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
bncdf80d44fd2016-07-15 20:27:415352 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195353 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
bncdf80d44fd2016-07-15 20:27:415354 SpdySerializedFrame window_update(
5355 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045356
5357 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415358 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5359 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045360 };
5361
[email protected]d9da5fe2010-10-13 22:37:165362 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415363 CreateMockRead(conn_resp, 1, ASYNC),
5364 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5365 CreateMockRead(wrapped_body, 4, ASYNC),
5366 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135367 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165368 };
5369
rch8e6c6c42015-05-01 14:05:135370 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5371 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075372 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165373
[email protected]8ddf8322012-02-23 18:08:065374 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365375 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065377 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165379
[email protected]49639fa2011-12-20 23:22:415380 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165381
bnc691fda62016-08-12 00:43:165382 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015383 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165384
5385 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015386 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165387
[email protected]58e32bb2013-01-21 18:23:255388 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165389 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255390 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5391
bnc691fda62016-08-12 00:43:165392 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525393 ASSERT_TRUE(response);
5394 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165395 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5396
5397 std::string response_data;
bnc691fda62016-08-12 00:43:165398 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165399 EXPECT_EQ("1234567890", response_data);
5400}
5401
5402// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015403TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5404 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385405
[email protected]cb9bf6ca2011-01-28 13:15:275406 HttpRequestInfo request;
5407 request.method = "GET";
bncce36dca22015-04-21 22:11:235408 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105409 request.traffic_annotation =
5410 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275411
[email protected]d9da5fe2010-10-13 22:37:165412 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495413 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5414 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515415 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075416 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165418
bnc691fda62016-08-12 00:43:165419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165420
bncce36dca22015-04-21 22:11:235421 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415422 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235423 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5424 // fetch https://www.example.org/ via SPDY
5425 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415426 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495427 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415428 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155429 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415430 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155431 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415432 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025433 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415434 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5435 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025436 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415437 SpdySerializedFrame window_update_get_resp(
5438 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5439 SpdySerializedFrame window_update_body(
5440 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045441
5442 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415443 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5444 CreateMockWrite(window_update_get_resp, 6),
5445 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045446 };
5447
[email protected]d9da5fe2010-10-13 22:37:165448 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415449 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095450 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415451 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5452 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135453 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165454 };
5455
rch32320842015-05-16 15:57:095456 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5457 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075458 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165459
[email protected]8ddf8322012-02-23 18:08:065460 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365461 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065463 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365464 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165466
[email protected]49639fa2011-12-20 23:22:415467 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165468
bnc691fda62016-08-12 00:43:165469 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165471
rch32320842015-05-16 15:57:095472 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555473 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095474 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595475 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165476 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015477 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165478
[email protected]58e32bb2013-01-21 18:23:255479 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165480 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255481 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5482
bnc691fda62016-08-12 00:43:165483 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525484 ASSERT_TRUE(response);
5485 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025486 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165487
5488 std::string response_data;
bnc691fda62016-08-12 00:43:165489 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235490 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165491}
5492
5493// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015494TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275495 HttpRequestInfo request;
5496 request.method = "GET";
bncce36dca22015-04-21 22:11:235497 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105498 request.traffic_annotation =
5499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275500
[email protected]d9da5fe2010-10-13 22:37:165501 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495502 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5503 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515504 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075505 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165507
bnc691fda62016-08-12 00:43:165508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165509
bncce36dca22015-04-21 22:11:235510 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415511 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235512 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415513 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085514 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165515
5516 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415517 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165518 };
5519
bnc42331402016-07-25 13:36:155520 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415521 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165522 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415523 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165524 };
5525
rch8e6c6c42015-05-01 14:05:135526 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5527 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075528 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165529
[email protected]8ddf8322012-02-23 18:08:065530 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365531 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065533 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365534 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075535 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165536
[email protected]49639fa2011-12-20 23:22:415537 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165538
bnc691fda62016-08-12 00:43:165539 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165541
5542 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015543 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165544
ttuttle960fcbf2016-04-19 13:26:325545 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165546}
5547
[email protected]f6c63db52013-02-02 00:35:225548// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5549// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015550TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225551 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5552 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495553 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5554 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515555 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075556 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095557 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505558 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225559
5560 HttpRequestInfo request1;
5561 request1.method = "GET";
bncce36dca22015-04-21 22:11:235562 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225563 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105564 request1.traffic_annotation =
5565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225566
5567 HttpRequestInfo request2;
5568 request2.method = "GET";
bncce36dca22015-04-21 22:11:235569 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225570 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105571 request2.traffic_annotation =
5572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225573
bncce36dca22015-04-21 22:11:235574 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415575 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235576 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155577 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225578
bncce36dca22015-04-21 22:11:235579 // Fetch https://www.example.org/ via HTTP.
5580 const char get1[] =
5581 "GET / HTTP/1.1\r\n"
5582 "Host: www.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_get1(
Bence Békyd74f4382018-02-20 18:26:195585 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225586 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5587 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415588 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195589 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415590 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195591 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415592 SpdySerializedFrame window_update(
5593 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225594
bncce36dca22015-04-21 22:11:235595 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295596 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275597 connect2_block[kHttp2MethodHeader] = "CONNECT";
5598 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155599 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5600 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395601
bnc42331402016-07-25 13:36:155602 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225603
bncce36dca22015-04-21 22:11:235604 // Fetch https://mail.example.org/ via HTTP.
5605 const char get2[] =
5606 "GET / HTTP/1.1\r\n"
5607 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225608 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415609 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195610 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225611 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5612 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415613 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195614 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
bncdf80d44fd2016-07-15 20:27:415615 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195616 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225617
5618 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415619 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5620 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225621 };
5622
5623 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415624 CreateMockRead(conn_resp1, 1, ASYNC),
5625 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5626 CreateMockRead(wrapped_body1, 4, ASYNC),
5627 CreateMockRead(conn_resp2, 6, ASYNC),
5628 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5629 CreateMockRead(wrapped_body2, 9, ASYNC),
5630 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225631 };
5632
mmenke11eb5152015-06-09 14:50:505633 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5634 arraysize(spdy_writes));
5635 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225636
5637 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365638 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505639 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225640 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505641 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225642 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505643 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225644
5645 TestCompletionCallback callback;
5646
bnc691fda62016-08-12 00:43:165647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205648 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015649 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225650
5651 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165652 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225653 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5654
bnc691fda62016-08-12 00:43:165655 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525656 ASSERT_TRUE(response);
5657 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225658 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5659
5660 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295661 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165662 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505663 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225664
bnc691fda62016-08-12 00:43:165665 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205666 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015667 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225668
5669 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165670 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225671 // Even though the SPDY connection is reused, a new tunnelled connection has
5672 // to be created, so the socket's load timing looks like a fresh connection.
5673 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5674
5675 // The requests should have different IDs, since they each are using their own
5676 // separate stream.
5677 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5678
bnc691fda62016-08-12 00:43:165679 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505680 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225681}
5682
5683// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5684// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015685TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225686 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5687 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495688 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5689 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515690 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075691 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095692 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505693 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225694
5695 HttpRequestInfo request1;
5696 request1.method = "GET";
bncce36dca22015-04-21 22:11:235697 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225698 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105699 request1.traffic_annotation =
5700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225701
5702 HttpRequestInfo request2;
5703 request2.method = "GET";
bncce36dca22015-04-21 22:11:235704 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225705 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105706 request2.traffic_annotation =
5707 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225708
bncce36dca22015-04-21 22:11:235709 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415710 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235711 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155712 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225713
bncce36dca22015-04-21 22:11:235714 // Fetch https://www.example.org/ via HTTP.
5715 const char get1[] =
5716 "GET / HTTP/1.1\r\n"
5717 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225718 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415719 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195720 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225721 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5722 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415723 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195724 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415725 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195726 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415727 SpdySerializedFrame window_update(
5728 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225729
bncce36dca22015-04-21 22:11:235730 // Fetch https://www.example.org/2 via HTTP.
5731 const char get2[] =
5732 "GET /2 HTTP/1.1\r\n"
5733 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225734 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415735 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195736 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225737 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5738 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415739 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195740 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
bncdf80d44fd2016-07-15 20:27:415741 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195742 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225743
5744 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415745 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5746 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225747 };
5748
5749 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415750 CreateMockRead(conn_resp1, 1, ASYNC),
5751 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465752 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415753 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465754 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415755 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225756 };
5757
mmenke11eb5152015-06-09 14:50:505758 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5759 arraysize(spdy_writes));
5760 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225761
5762 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365763 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225765 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225767
5768 TestCompletionCallback callback;
5769
bnc87dcefc2017-05-25 12:47:585770 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195771 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205772 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225774
5775 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015776 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225777
5778 LoadTimingInfo load_timing_info;
5779 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5780 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5781
5782 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525783 ASSERT_TRUE(response);
5784 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225785 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5786
5787 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295788 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505789 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225790 trans.reset();
5791
bnc87dcefc2017-05-25 12:47:585792 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195793 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205794 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225796
[email protected]f6c63db52013-02-02 00:35:225797 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015798 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225799
5800 LoadTimingInfo load_timing_info2;
5801 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5802 TestLoadTimingReused(load_timing_info2);
5803
5804 // The requests should have the same ID.
5805 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5806
[email protected]90499482013-06-01 00:39:505807 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225808}
5809
5810// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5811// Proxy to different servers.
bncd16676a2016-07-20 16:23:015812TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225813 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495814 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5815 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515816 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075817 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095818 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505819 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225820
5821 HttpRequestInfo request1;
5822 request1.method = "GET";
bncce36dca22015-04-21 22:11:235823 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225824 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105825 request1.traffic_annotation =
5826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225827
5828 HttpRequestInfo request2;
5829 request2.method = "GET";
bncce36dca22015-04-21 22:11:235830 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225831 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105832 request2.traffic_annotation =
5833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225834
bncce36dca22015-04-21 22:11:235835 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265836 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235837 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415838 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155839 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5840 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Bence Békyd74f4382018-02-20 18:26:195841 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385842 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225843
bncce36dca22015-04-21 22:11:235844 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265845 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235846 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415847 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155848 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5849 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
Bence Békyd74f4382018-02-20 18:26:195850 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225851
5852 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415853 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225854 };
5855
5856 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415857 CreateMockRead(get_resp1, 1, ASYNC),
5858 CreateMockRead(body1, 2, ASYNC),
5859 CreateMockRead(get_resp2, 4, ASYNC),
5860 CreateMockRead(body2, 5, ASYNC),
5861 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225862 };
5863
mmenke11eb5152015-06-09 14:50:505864 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5865 arraysize(spdy_writes));
5866 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225867
5868 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365869 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225871
5872 TestCompletionCallback callback;
5873
bnc87dcefc2017-05-25 12:47:585874 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205876 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015877 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225878
5879 LoadTimingInfo load_timing_info;
5880 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5881 TestLoadTimingNotReused(load_timing_info,
5882 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5883
5884 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525885 ASSERT_TRUE(response);
5886 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025887 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225888
5889 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295890 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505891 rv = trans->Read(buf.get(), 256, callback.callback());
5892 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225893 // Delete the first request, so the second one can reuse the socket.
5894 trans.reset();
5895
bnc691fda62016-08-12 00:43:165896 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205897 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015898 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225899
5900 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165901 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225902 TestLoadTimingReused(load_timing_info2);
5903
5904 // The requests should have the same ID.
5905 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5906
bnc691fda62016-08-12 00:43:165907 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505908 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225909}
5910
[email protected]2df19bb2010-08-25 20:13:465911// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015912TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465913 HttpRequestInfo request;
5914 request.method = "GET";
bncce36dca22015-04-21 22:11:235915 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465916 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295917 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:105918 request.traffic_annotation =
5919 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465920
[email protected]79cb5c12011-09-12 13:12:045921 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495922 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5923 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515924 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075925 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095926 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275927
[email protected]2df19bb2010-08-25 20:13:465928 // Since we have proxy, should use full url
5929 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165930 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5931 "Host: www.example.org\r\n"
5932 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465933
bnc691fda62016-08-12 00:43:165934 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235935 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165936 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5937 "Host: www.example.org\r\n"
5938 "Proxy-Connection: keep-alive\r\n"
5939 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465940 };
5941
5942 // The proxy responds to the GET with a 407, using a persistent
5943 // connection.
5944 MockRead data_reads1[] = {
5945 // No credentials.
5946 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5947 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5948 MockRead("Proxy-Connection: keep-alive\r\n"),
5949 MockRead("Content-Length: 0\r\n\r\n"),
5950
5951 MockRead("HTTP/1.1 200 OK\r\n"),
5952 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5953 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065954 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465955 };
5956
5957 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5958 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075959 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065960 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075961 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465962
[email protected]49639fa2011-12-20 23:22:415963 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465964
bnc691fda62016-08-12 00:43:165965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505966
bnc691fda62016-08-12 00:43:165967 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465969
5970 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015971 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465972
[email protected]58e32bb2013-01-21 18:23:255973 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165974 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255975 TestLoadTimingNotReused(load_timing_info,
5976 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5977
bnc691fda62016-08-12 00:43:165978 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525979 ASSERT_TRUE(response);
5980 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465981 EXPECT_EQ(407, response->headers->response_code());
5982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435983 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465984
[email protected]49639fa2011-12-20 23:22:415985 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465986
bnc691fda62016-08-12 00:43:165987 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465989
5990 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015991 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465992
[email protected]58e32bb2013-01-21 18:23:255993 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165994 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255995 // Retrying with HTTP AUTH is considered to be reusing a socket.
5996 TestLoadTimingReused(load_timing_info);
5997
bnc691fda62016-08-12 00:43:165998 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525999 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466000
6001 EXPECT_TRUE(response->headers->IsKeepAlive());
6002 EXPECT_EQ(200, response->headers->response_code());
6003 EXPECT_EQ(100, response->headers->GetContentLength());
6004 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6005
6006 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526007 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466008}
6009
[email protected]23e482282013-06-14 16:08:026010void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086011 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426012 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086013 request.method = "GET";
bncce36dca22015-04-21 22:11:236014 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106015 request.traffic_annotation =
6016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086017
[email protected]cb9bf6ca2011-01-28 13:15:276018 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496019 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6020 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096021 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276022
[email protected]c744cf22009-02-27 07:28:086023 // Since we have proxy, should try to establish tunnel.
6024 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176025 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6026 "Host: www.example.org:443\r\n"
6027 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086028 };
6029
6030 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236031 status, MockRead("Content-Length: 10\r\n\r\n"),
6032 // No response body because the test stops reading here.
6033 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086034 };
6035
[email protected]31a2bfe2010-02-09 08:03:396036 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6037 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076038 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086039
[email protected]49639fa2011-12-20 23:22:416040 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086041
bnc691fda62016-08-12 00:43:166042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506043
tfarina42834112016-09-22 13:38:206044 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086046
6047 rv = callback.WaitForResult();
6048 EXPECT_EQ(expected_status, rv);
6049}
6050
[email protected]23e482282013-06-14 16:08:026051void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236052 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086053 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426054 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086055}
6056
bncd16676a2016-07-20 16:23:016057TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086058 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6059}
6060
bncd16676a2016-07-20 16:23:016061TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086062 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6063}
6064
bncd16676a2016-07-20 16:23:016065TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086066 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6067}
6068
bncd16676a2016-07-20 16:23:016069TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086070 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6071}
6072
bncd16676a2016-07-20 16:23:016073TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086074 ConnectStatusHelper(
6075 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6076}
6077
bncd16676a2016-07-20 16:23:016078TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086079 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6080}
6081
bncd16676a2016-07-20 16:23:016082TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086083 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6084}
6085
bncd16676a2016-07-20 16:23:016086TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086087 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6088}
6089
bncd16676a2016-07-20 16:23:016090TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086091 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6092}
6093
bncd16676a2016-07-20 16:23:016094TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086095 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6096}
6097
bncd16676a2016-07-20 16:23:016098TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086099 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6100}
6101
bncd16676a2016-07-20 16:23:016102TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086103 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6104}
6105
bncd16676a2016-07-20 16:23:016106TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086107 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6108}
6109
bncd16676a2016-07-20 16:23:016110TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086111 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6112}
6113
bncd16676a2016-07-20 16:23:016114TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086115 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6116}
6117
bncd16676a2016-07-20 16:23:016118TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086119 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6120}
6121
bncd16676a2016-07-20 16:23:016122TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376123 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6124}
6125
bncd16676a2016-07-20 16:23:016126TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086127 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6128}
6129
bncd16676a2016-07-20 16:23:016130TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086131 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6132}
6133
bncd16676a2016-07-20 16:23:016134TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086135 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6136}
6137
bncd16676a2016-07-20 16:23:016138TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086139 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6140}
6141
bncd16676a2016-07-20 16:23:016142TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086143 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6144}
6145
bncd16676a2016-07-20 16:23:016146TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086147 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6148}
6149
bncd16676a2016-07-20 16:23:016150TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086151 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6152}
6153
bncd16676a2016-07-20 16:23:016154TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086155 ConnectStatusHelperWithExpectedStatus(
6156 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546157 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086158}
6159
bncd16676a2016-07-20 16:23:016160TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086161 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6162}
6163
bncd16676a2016-07-20 16:23:016164TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086165 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6166}
6167
bncd16676a2016-07-20 16:23:016168TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086169 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6170}
6171
bncd16676a2016-07-20 16:23:016172TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086173 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6174}
6175
bncd16676a2016-07-20 16:23:016176TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086177 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6178}
6179
bncd16676a2016-07-20 16:23:016180TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086181 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6182}
6183
bncd16676a2016-07-20 16:23:016184TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086185 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6186}
6187
bncd16676a2016-07-20 16:23:016188TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086189 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6190}
6191
bncd16676a2016-07-20 16:23:016192TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086193 ConnectStatusHelper(
6194 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6195}
6196
bncd16676a2016-07-20 16:23:016197TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086198 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6199}
6200
bncd16676a2016-07-20 16:23:016201TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086202 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6203}
6204
bncd16676a2016-07-20 16:23:016205TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086206 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6207}
6208
bncd16676a2016-07-20 16:23:016209TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086210 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6211}
6212
bncd16676a2016-07-20 16:23:016213TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086214 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6215}
6216
bncd16676a2016-07-20 16:23:016217TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086218 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6219}
6220
bncd16676a2016-07-20 16:23:016221TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086222 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6223}
6224
[email protected]038e9a32008-10-08 22:40:166225// Test the flow when both the proxy server AND origin server require
6226// authentication. Again, this uses basic auth for both since that is
6227// the simplest to mock.
bncd16676a2016-07-20 16:23:016228TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276229 HttpRequestInfo request;
6230 request.method = "GET";
bncce36dca22015-04-21 22:11:236231 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106232 request.traffic_annotation =
6233 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276234
[email protected]038e9a32008-10-08 22:40:166235 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496236 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6237 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076239
bnc691fda62016-08-12 00:43:166240 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166241
[email protected]f9ee6b52008-11-08 06:46:236242 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236243 MockWrite(
6244 "GET http://www.example.org/ HTTP/1.1\r\n"
6245 "Host: www.example.org\r\n"
6246 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236247 };
6248
[email protected]038e9a32008-10-08 22:40:166249 MockRead data_reads1[] = {
6250 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6251 // Give a couple authenticate options (only the middle one is actually
6252 // supported).
[email protected]22927ad2009-09-21 19:56:196253 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166254 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6255 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6256 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6257 // Large content-length -- won't matter, as connection will be reset.
6258 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066259 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166260 };
6261
bnc691fda62016-08-12 00:43:166262 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166263 // request we should be issuing -- the final header line contains the
6264 // proxy's credentials.
6265 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236266 MockWrite(
6267 "GET http://www.example.org/ HTTP/1.1\r\n"
6268 "Host: www.example.org\r\n"
6269 "Proxy-Connection: keep-alive\r\n"
6270 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166271 };
6272
6273 // Now the proxy server lets the request pass through to origin server.
6274 // The origin server responds with a 401.
6275 MockRead data_reads2[] = {
6276 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6277 // Note: We are using the same realm-name as the proxy server. This is
6278 // completely valid, as realms are unique across hosts.
6279 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6280 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6281 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066282 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166283 };
6284
bnc691fda62016-08-12 00:43:166285 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166286 // the credentials for both the proxy and origin server.
6287 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236288 MockWrite(
6289 "GET http://www.example.org/ HTTP/1.1\r\n"
6290 "Host: www.example.org\r\n"
6291 "Proxy-Connection: keep-alive\r\n"
6292 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6293 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166294 };
6295
6296 // Lastly we get the desired content.
6297 MockRead data_reads3[] = {
6298 MockRead("HTTP/1.0 200 OK\r\n"),
6299 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6300 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066301 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166302 };
6303
[email protected]31a2bfe2010-02-09 08:03:396304 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6305 data_writes1, arraysize(data_writes1));
6306 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6307 data_writes2, arraysize(data_writes2));
6308 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6309 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6312 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166313
[email protected]49639fa2011-12-20 23:22:416314 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166315
tfarina42834112016-09-22 13:38:206316 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166318
6319 rv = callback1.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 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526323 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046324 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166325
[email protected]49639fa2011-12-20 23:22:416326 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166327
bnc691fda62016-08-12 00:43:166328 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166330
6331 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016332 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166333
bnc691fda62016-08-12 00:43:166334 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526335 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046336 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166337
[email protected]49639fa2011-12-20 23:22:416338 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166339
bnc691fda62016-08-12 00:43:166340 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6341 callback3.callback());
robpercival214763f2016-07-01 23:27:016342 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166343
6344 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016345 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166346
bnc691fda62016-08-12 00:43:166347 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526348 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166349 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166350}
[email protected]4ddaf2502008-10-23 18:26:196351
[email protected]ea9dc9a2009-09-05 00:43:326352// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6353// can't hook into its internals to cause it to generate predictable NTLM
6354// authorization headers.
6355#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376356// The NTLM authentication unit tests are based on known test data from the
6357// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6358// flow rather than the implementation of the NTLM protocol. See net/ntlm
6359// for the implementation and testing of the protocol.
6360//
6361// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296362
6363// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556364TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426365 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246366 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556367 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106368 request.traffic_annotation =
6369 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546370
6371 // Ensure load is not disrupted by flags which suppress behaviour specific
6372 // to other auth schemes.
6373 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246374
Zentaro Kavanagh6ccee512017-09-28 18:34:096375 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6376 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276378
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376379 // Generate the NTLM messages based on known test data.
6380 std::string negotiate_msg;
6381 std::string challenge_msg;
6382 std::string authenticate_msg;
6383 base::Base64Encode(
6384 base::StringPiece(
6385 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6386 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6387 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556388 base::Base64Encode(
6389 base::StringPiece(
6390 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6391 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6392 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376393 base::Base64Encode(
6394 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096395 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556396 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6397 arraysize(
6398 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376399 &authenticate_msg);
6400
[email protected]3f918782009-02-28 01:29:246401 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556402 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6403 "Host: server\r\n"
6404 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246405 };
6406
6407 MockRead data_reads1[] = {
6408 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046409 // Negotiate and NTLM are often requested together. However, we only want
6410 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6411 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246412 MockRead("WWW-Authenticate: NTLM\r\n"),
6413 MockRead("Connection: close\r\n"),
6414 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366415 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246416 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246417 };
6418
6419 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166420 // After restarting with a null identity, this is the
6421 // request we should be issuing -- the final header line contains a Type
6422 // 1 message.
6423 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556424 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166425 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376426 "Authorization: NTLM "),
6427 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246428
bnc691fda62016-08-12 00:43:166429 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376430 // (using correct credentials). The second request continues on the
6431 // same connection.
bnc691fda62016-08-12 00:43:166432 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556433 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166434 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376435 "Authorization: NTLM "),
6436 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246437 };
6438
6439 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026440 // The origin server responds with a Type 2 message.
6441 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376442 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6443 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026444 MockRead("Content-Type: text/html\r\n\r\n"),
6445 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246446
Bence Béky1e4ef192017-09-18 19:58:026447 // Lastly we get the desired content.
6448 MockRead("HTTP/1.1 200 OK\r\n"),
6449 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6450 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246451 };
6452
[email protected]31a2bfe2010-02-09 08:03:396453 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6454 data_writes1, arraysize(data_writes1));
6455 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6456 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076457 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6458 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246459
Bence Béky83eb3512017-09-05 12:56:096460 SSLSocketDataProvider ssl1(ASYNC, OK);
6461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6462 SSLSocketDataProvider ssl2(ASYNC, OK);
6463 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6464
[email protected]49639fa2011-12-20 23:22:416465 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246466
bnc691fda62016-08-12 00:43:166467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506468
tfarina42834112016-09-22 13:38:206469 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246471
6472 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016473 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246474
bnc691fda62016-08-12 00:43:166475 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226476
bnc691fda62016-08-12 00:43:166477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526478 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046479 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246480
[email protected]49639fa2011-12-20 23:22:416481 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256482
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376483 rv = trans.RestartWithAuth(
6484 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6485 callback2.callback());
robpercival214763f2016-07-01 23:27:016486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256487
6488 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016489 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256490
bnc691fda62016-08-12 00:43:166491 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256492
bnc691fda62016-08-12 00:43:166493 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526494 ASSERT_TRUE(response);
6495 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256496
[email protected]49639fa2011-12-20 23:22:416497 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246498
bnc691fda62016-08-12 00:43:166499 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246501
[email protected]0757e7702009-03-27 04:00:226502 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016503 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246504
bnc691fda62016-08-12 00:43:166505 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526506 ASSERT_TRUE(response);
6507 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026508 EXPECT_EQ(14, response->headers->GetContentLength());
6509
6510 std::string response_data;
6511 rv = ReadTransaction(&trans, &response_data);
6512 EXPECT_THAT(rv, IsOk());
6513 EXPECT_EQ("Please Login\r\n", response_data);
6514
6515 EXPECT_TRUE(data1.AllReadDataConsumed());
6516 EXPECT_TRUE(data1.AllWriteDataConsumed());
6517 EXPECT_TRUE(data2.AllReadDataConsumed());
6518 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246519}
6520
[email protected]385a4672009-03-11 22:21:296521// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556522TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426523 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296524 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556525 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106526 request.traffic_annotation =
6527 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296528
Zentaro Kavanagh6ccee512017-09-28 18:34:096529 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6530 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276532
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376533 // Generate the NTLM messages based on known test data.
6534 std::string negotiate_msg;
6535 std::string challenge_msg;
6536 std::string authenticate_msg;
6537 base::Base64Encode(
6538 base::StringPiece(
6539 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6540 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6541 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556542 base::Base64Encode(
6543 base::StringPiece(
6544 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6545 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6546 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376547 base::Base64Encode(
6548 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096549 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556550 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6551 arraysize(
6552 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376553 &authenticate_msg);
6554
6555 // The authenticate message when |kWrongPassword| is sent.
6556 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556557 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6558 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6559 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6560 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6561 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6562 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376563
Zentaro Kavanagh1890a3d2018-01-29 19:52:556564 // Sanity check that it's the same length as the correct authenticate message
6565 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376566 ASSERT_EQ(authenticate_msg.length(),
6567 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556568 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376569
[email protected]385a4672009-03-11 22:21:296570 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556571 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6572 "Host: server\r\n"
6573 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296574 };
6575
6576 MockRead data_reads1[] = {
6577 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046578 // Negotiate and NTLM are often requested together. However, we only want
6579 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6580 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296581 MockRead("WWW-Authenticate: NTLM\r\n"),
6582 MockRead("Connection: close\r\n"),
6583 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366584 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296585 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296586 };
6587
6588 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166589 // After restarting with a null identity, this is the
6590 // request we should be issuing -- the final header line contains a Type
6591 // 1 message.
6592 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556593 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166594 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376595 "Authorization: NTLM "),
6596 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296597
bnc691fda62016-08-12 00:43:166598 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376599 // (using incorrect credentials). The second request continues on the
6600 // same connection.
bnc691fda62016-08-12 00:43:166601 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556602 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166603 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376604 "Authorization: NTLM "),
6605 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296606 };
6607
6608 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376609 // The origin server responds with a Type 2 message.
6610 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6611 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6612 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6613 MockRead("Content-Type: text/html\r\n\r\n"),
6614 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296615
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376616 // Wrong password.
6617 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6618 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6619 MockRead("Content-Length: 42\r\n"),
6620 MockRead("Content-Type: text/html\r\n\r\n"),
6621 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296622 };
6623
6624 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166625 // After restarting with a null identity, this is the
6626 // request we should be issuing -- the final header line contains a Type
6627 // 1 message.
6628 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556629 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166630 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376631 "Authorization: NTLM "),
6632 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296633
bnc691fda62016-08-12 00:43:166634 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6635 // (the credentials for the origin server). The second request continues
6636 // on the same connection.
6637 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556638 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166639 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376640 "Authorization: NTLM "),
6641 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296642 };
6643
6644 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026645 // The origin server responds with a Type 2 message.
6646 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376647 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6648 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026649 MockRead("Content-Type: text/html\r\n\r\n"),
6650 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296651
Bence Béky1e4ef192017-09-18 19:58:026652 // Lastly we get the desired content.
6653 MockRead("HTTP/1.1 200 OK\r\n"),
6654 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6655 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296656 };
6657
[email protected]31a2bfe2010-02-09 08:03:396658 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6659 data_writes1, arraysize(data_writes1));
6660 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6661 data_writes2, arraysize(data_writes2));
6662 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6663 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6665 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6666 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296667
Bence Béky83eb3512017-09-05 12:56:096668 SSLSocketDataProvider ssl1(ASYNC, OK);
6669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6670 SSLSocketDataProvider ssl2(ASYNC, OK);
6671 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6672 SSLSocketDataProvider ssl3(ASYNC, OK);
6673 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6674
[email protected]49639fa2011-12-20 23:22:416675 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296676
bnc691fda62016-08-12 00:43:166677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506678
tfarina42834112016-09-22 13:38:206679 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296681
6682 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016683 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296684
bnc691fda62016-08-12 00:43:166685 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296686
bnc691fda62016-08-12 00:43:166687 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526688 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046689 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296690
[email protected]49639fa2011-12-20 23:22:416691 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296692
[email protected]0757e7702009-03-27 04:00:226693 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376694 rv = trans.RestartWithAuth(
6695 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6696 callback2.callback());
robpercival214763f2016-07-01 23:27:016697 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296698
[email protected]10af5fe72011-01-31 16:17:256699 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016700 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296701
bnc691fda62016-08-12 00:43:166702 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416703 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166704 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256706 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016707 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166708 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226709
bnc691fda62016-08-12 00:43:166710 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526711 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046712 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226713
[email protected]49639fa2011-12-20 23:22:416714 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226715
6716 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376717 rv = trans.RestartWithAuth(
6718 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6719 callback4.callback());
robpercival214763f2016-07-01 23:27:016720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256721
6722 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016723 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256724
bnc691fda62016-08-12 00:43:166725 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256726
[email protected]49639fa2011-12-20 23:22:416727 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256728
6729 // One more roundtrip
bnc691fda62016-08-12 00:43:166730 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226732
6733 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016734 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226735
bnc691fda62016-08-12 00:43:166736 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526737 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026738 EXPECT_EQ(14, response->headers->GetContentLength());
6739
6740 std::string response_data;
6741 rv = ReadTransaction(&trans, &response_data);
6742 EXPECT_THAT(rv, IsOk());
6743 EXPECT_EQ("Please Login\r\n", response_data);
6744
6745 EXPECT_TRUE(data1.AllReadDataConsumed());
6746 EXPECT_TRUE(data1.AllWriteDataConsumed());
6747 EXPECT_TRUE(data2.AllReadDataConsumed());
6748 EXPECT_TRUE(data2.AllWriteDataConsumed());
6749 EXPECT_TRUE(data3.AllReadDataConsumed());
6750 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296751}
Bence Béky83eb3512017-09-05 12:56:096752
Bence Béky3238f2e12017-09-22 22:44:496753// Server requests NTLM authentication, which is not supported over HTTP/2.
6754// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096755TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096756 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6757 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096758
Zentaro Kavanagh1890a3d2018-01-29 19:52:556759 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096760
6761 HttpRequestInfo request;
6762 request.method = "GET";
6763 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:106764 request.traffic_annotation =
6765 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096766
6767 // First request without credentials.
6768 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6769 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6770 1, std::move(request_headers0), LOWEST, true));
6771
6772 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276773 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096774 response_headers0["www-authenticate"] = "NTLM";
6775 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6776 1, std::move(response_headers0), true));
6777
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376778 // Stream 1 is closed.
6779 spdy_util_.UpdateWithStreamDestruction(1);
6780
6781 // Generate the NTLM messages based on known test data.
6782 std::string negotiate_msg;
6783 std::string challenge_msg;
6784 std::string authenticate_msg;
6785 base::Base64Encode(
6786 base::StringPiece(
6787 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6788 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6789 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556790 base::Base64Encode(
6791 base::StringPiece(
6792 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6793 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6794 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376795 base::Base64Encode(
6796 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096797 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556798 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6799 arraysize(
6800 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376801 &authenticate_msg);
6802
6803 // Retry with authorization header.
6804 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6805 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6806 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6807 3, std::move(request_headers1), LOWEST, true));
6808
6809 SpdySerializedFrame rst(
6810 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6811
Bence Béky3238f2e12017-09-22 22:44:496812 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6813 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096814
6815 // Retry yet again using HTTP/1.1.
6816 MockWrite writes1[] = {
6817 // After restarting with a null identity, this is the
6818 // request we should be issuing -- the final header line contains a Type
6819 // 1 message.
6820 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556821 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096822 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376823 "Authorization: NTLM "),
6824 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096825
6826 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6827 // (the credentials for the origin server). The second request continues
6828 // on the same connection.
6829 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556830 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096831 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376832 "Authorization: NTLM "),
6833 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096834 };
6835
6836 MockRead reads1[] = {
6837 // The origin server responds with a Type 2 message.
6838 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376839 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6840 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096841 MockRead("Content-Type: text/html\r\n\r\n"),
6842 MockRead("You are not authorized to view this page\r\n"),
6843
6844 // Lastly we get the desired content.
6845 MockRead("HTTP/1.1 200 OK\r\n"),
6846 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026847 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096848 };
6849 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6850 arraysize(writes0));
6851 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6852 arraysize(writes1));
6853 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6855
6856 SSLSocketDataProvider ssl0(ASYNC, OK);
6857 ssl0.next_proto = kProtoHTTP2;
6858 SSLSocketDataProvider ssl1(ASYNC, OK);
6859 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6861
6862 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6864
6865 TestCompletionCallback callback1;
6866 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6868
6869 rv = callback1.WaitForResult();
6870 EXPECT_THAT(rv, IsOk());
6871
6872 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6873
6874 const HttpResponseInfo* response = trans.GetResponseInfo();
6875 ASSERT_TRUE(response);
6876 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6877
6878 TestCompletionCallback callback2;
6879
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376880 rv = trans.RestartWithAuth(
6881 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6882 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6884
6885 rv = callback2.WaitForResult();
6886 EXPECT_THAT(rv, IsOk());
6887
6888 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6889
6890 response = trans.GetResponseInfo();
6891 ASSERT_TRUE(response);
6892 EXPECT_FALSE(response->auth_challenge);
6893
6894 TestCompletionCallback callback3;
6895
6896 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6898
6899 rv = callback3.WaitForResult();
6900 EXPECT_THAT(rv, IsOk());
6901
6902 response = trans.GetResponseInfo();
6903 ASSERT_TRUE(response);
6904 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026905 EXPECT_EQ(14, response->headers->GetContentLength());
6906
6907 std::string response_data;
6908 rv = ReadTransaction(&trans, &response_data);
6909 EXPECT_THAT(rv, IsOk());
6910 EXPECT_EQ("Please Login\r\n", response_data);
6911
6912 EXPECT_TRUE(data0.AllReadDataConsumed());
6913 EXPECT_TRUE(data0.AllWriteDataConsumed());
6914 EXPECT_TRUE(data1.AllReadDataConsumed());
6915 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096916}
[email protected]ea9dc9a2009-09-05 00:43:326917#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296918
[email protected]4ddaf2502008-10-23 18:26:196919// Test reading a server response which has only headers, and no body.
6920// After some maximum number of bytes is consumed, the transaction should
6921// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426923 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196924 request.method = "GET";
bncce36dca22015-04-21 22:11:236925 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106926 request.traffic_annotation =
6927 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196928
danakj1fd259a02016-04-16 03:17:096929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166930 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276931
[email protected]b75b7b2f2009-10-06 00:54:536932 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436933 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536934 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196935
6936 MockRead data_reads[] = {
6937 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066938 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196939 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066940 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196941 };
[email protected]31a2bfe2010-02-09 08:03:396942 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076943 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196944
[email protected]49639fa2011-12-20 23:22:416945 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196946
tfarina42834112016-09-22 13:38:206947 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196949
6950 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016951 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196952}
[email protected]f4e426b2008-11-05 00:24:496953
6954// Make sure that we don't try to reuse a TCPClientSocket when failing to
6955// establish tunnel.
6956// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016957TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276958 HttpRequestInfo request;
6959 request.method = "GET";
bncce36dca22015-04-21 22:11:236960 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106961 request.traffic_annotation =
6962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276963
[email protected]f4e426b2008-11-05 00:24:496964 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496965 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6966 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:016967
danakj1fd259a02016-04-16 03:17:096968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496969
bnc87dcefc2017-05-25 12:47:586970 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196971 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496972
[email protected]f4e426b2008-11-05 00:24:496973 // Since we have proxy, should try to establish tunnel.
6974 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176975 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6976 "Host: www.example.org:443\r\n"
6977 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496978 };
6979
[email protected]77848d12008-11-14 00:00:226980 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496981 // connection. Usually a proxy would return 501 (not implemented),
6982 // or 200 (tunnel established).
6983 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236984 MockRead("HTTP/1.1 404 Not Found\r\n"),
6985 MockRead("Content-Length: 10\r\n\r\n"),
6986 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496987 };
6988
[email protected]31a2bfe2010-02-09 08:03:396989 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6990 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076991 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496992
[email protected]49639fa2011-12-20 23:22:416993 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496994
tfarina42834112016-09-22 13:38:206995 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496997
6998 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016999 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497000
[email protected]b4404c02009-04-10 16:38:527001 // Empty the current queue. This is necessary because idle sockets are
7002 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557003 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527004
[email protected]f4e426b2008-11-05 00:24:497005 // We now check to make sure the TCPClientSocket was not added back to
7006 // the pool.
[email protected]90499482013-06-01 00:39:507007 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497008 trans.reset();
fdoray92e35a72016-06-10 15:54:557009 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497010 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507011 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497012}
[email protected]372d34a2008-11-05 21:30:517013
[email protected]1b157c02009-04-21 01:55:407014// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017015TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427016 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407017 request.method = "GET";
bncce36dca22015-04-21 22:11:237018 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107019 request.traffic_annotation =
7020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407021
danakj1fd259a02016-04-16 03:17:097022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277023
bnc691fda62016-08-12 00:43:167024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277025
[email protected]1b157c02009-04-21 01:55:407026 MockRead data_reads[] = {
7027 // A part of the response body is received with the response headers.
7028 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7029 // The rest of the response body is received in two parts.
7030 MockRead("lo"),
7031 MockRead(" world"),
7032 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067033 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407034 };
7035
[email protected]31a2bfe2010-02-09 08:03:397036 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077037 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407038
[email protected]49639fa2011-12-20 23:22:417039 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407040
tfarina42834112016-09-22 13:38:207041 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407043
7044 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017045 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407046
bnc691fda62016-08-12 00:43:167047 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527048 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407049
wezca1070932016-05-26 20:30:527050 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407051 std::string status_line = response->headers->GetStatusLine();
7052 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7053
[email protected]90499482013-06-01 00:39:507054 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407055
7056 std::string response_data;
bnc691fda62016-08-12 00:43:167057 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017058 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407059 EXPECT_EQ("hello world", response_data);
7060
7061 // Empty the current queue. This is necessary because idle sockets are
7062 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557063 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407064
7065 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507066 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407067}
7068
[email protected]76a505b2010-08-25 06:23:007069// Make sure that we recycle a SSL socket after reading all of the response
7070// body.
bncd16676a2016-07-20 16:23:017071TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007072 HttpRequestInfo request;
7073 request.method = "GET";
bncce36dca22015-04-21 22:11:237074 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107075 request.traffic_annotation =
7076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007077
7078 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237079 MockWrite(
7080 "GET / HTTP/1.1\r\n"
7081 "Host: www.example.org\r\n"
7082 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007083 };
7084
7085 MockRead data_reads[] = {
7086 MockRead("HTTP/1.1 200 OK\r\n"),
7087 MockRead("Content-Length: 11\r\n\r\n"),
7088 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067089 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007090 };
7091
[email protected]8ddf8322012-02-23 18:08:067092 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007094
7095 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7096 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077097 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007098
[email protected]49639fa2011-12-20 23:22:417099 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007100
danakj1fd259a02016-04-16 03:17:097101 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007103
tfarina42834112016-09-22 13:38:207104 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007105
robpercival214763f2016-07-01 23:27:017106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7107 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007108
bnc691fda62016-08-12 00:43:167109 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527110 ASSERT_TRUE(response);
7111 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007112 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7113
[email protected]90499482013-06-01 00:39:507114 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007115
7116 std::string response_data;
bnc691fda62016-08-12 00:43:167117 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017118 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007119 EXPECT_EQ("hello world", response_data);
7120
7121 // Empty the current queue. This is necessary because idle sockets are
7122 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557123 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007124
7125 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507126 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007127}
7128
7129// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7130// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017131TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007132 HttpRequestInfo request;
7133 request.method = "GET";
bncce36dca22015-04-21 22:11:237134 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107135 request.traffic_annotation =
7136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007137
7138 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237139 MockWrite(
7140 "GET / HTTP/1.1\r\n"
7141 "Host: www.example.org\r\n"
7142 "Connection: keep-alive\r\n\r\n"),
7143 MockWrite(
7144 "GET / HTTP/1.1\r\n"
7145 "Host: www.example.org\r\n"
7146 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007147 };
7148
7149 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427150 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7151 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007152
[email protected]8ddf8322012-02-23 18:08:067153 SSLSocketDataProvider ssl(ASYNC, OK);
7154 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7156 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007157
7158 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7159 data_writes, arraysize(data_writes));
7160 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7161 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077162 session_deps_.socket_factory->AddSocketDataProvider(&data);
7163 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007164
[email protected]49639fa2011-12-20 23:22:417165 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007166
danakj1fd259a02016-04-16 03:17:097167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587168 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197169 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007170
tfarina42834112016-09-22 13:38:207171 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007172
robpercival214763f2016-07-01 23:27:017173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7174 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007175
7176 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527177 ASSERT_TRUE(response);
7178 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007179 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7180
[email protected]90499482013-06-01 00:39:507181 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007182
7183 std::string response_data;
7184 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017185 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007186 EXPECT_EQ("hello world", response_data);
7187
7188 // Empty the current queue. This is necessary because idle sockets are
7189 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557190 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007191
7192 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507193 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007194
7195 // Now start the second transaction, which should reuse the previous socket.
7196
bnc87dcefc2017-05-25 12:47:587197 trans =
Jeremy Roman0579ed62017-08-29 15:56:197198 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007199
tfarina42834112016-09-22 13:38:207200 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007201
robpercival214763f2016-07-01 23:27:017202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7203 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007204
7205 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527206 ASSERT_TRUE(response);
7207 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007208 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7209
[email protected]90499482013-06-01 00:39:507210 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007211
7212 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017213 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007214 EXPECT_EQ("hello world", response_data);
7215
7216 // Empty the current queue. This is necessary because idle sockets are
7217 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557218 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007219
7220 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507221 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007222}
7223
maksim.sisov0adf8592016-07-15 06:25:567224// Grab a socket, use it, and put it back into the pool. Then, make
7225// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017226TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567227 HttpRequestInfo request;
7228 request.method = "GET";
7229 request.url = GURL("http://www.example.org/");
7230 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107231 request.traffic_annotation =
7232 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567233
7234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7235
bnc691fda62016-08-12 00:43:167236 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567237
7238 MockRead data_reads[] = {
7239 // A part of the response body is received with the response headers.
7240 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7241 // The rest of the response body is received in two parts.
7242 MockRead("lo"), MockRead(" world"),
7243 MockRead("junk"), // Should not be read!!
7244 MockRead(SYNCHRONOUS, OK),
7245 };
7246
7247 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7248 session_deps_.socket_factory->AddSocketDataProvider(&data);
7249
7250 TestCompletionCallback callback;
7251
tfarina42834112016-09-22 13:38:207252 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7254
7255 EXPECT_THAT(callback.GetResult(rv), IsOk());
7256
bnc691fda62016-08-12 00:43:167257 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567258 ASSERT_TRUE(response);
7259 EXPECT_TRUE(response->headers);
7260 std::string status_line = response->headers->GetStatusLine();
7261 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7262
7263 // Make memory critical notification and ensure the transaction still has been
7264 // operating right.
7265 base::MemoryPressureListener::NotifyMemoryPressure(
7266 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7267 base::RunLoop().RunUntilIdle();
7268
7269 // Socket should not be flushed as long as it is not idle.
7270 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7271
7272 std::string response_data;
bnc691fda62016-08-12 00:43:167273 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567274 EXPECT_THAT(rv, IsOk());
7275 EXPECT_EQ("hello world", response_data);
7276
7277 // Empty the current queue. This is necessary because idle sockets are
7278 // added to the connection pool asynchronously with a PostTask.
7279 base::RunLoop().RunUntilIdle();
7280
7281 // We now check to make sure the socket was added back to the pool.
7282 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7283
7284 // Idle sockets should be flushed now.
7285 base::MemoryPressureListener::NotifyMemoryPressure(
7286 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7287 base::RunLoop().RunUntilIdle();
7288
7289 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7290}
7291
yucliu48f235d2018-01-11 00:59:557292// Disable idle socket closing on memory pressure.
7293// Grab a socket, use it, and put it back into the pool. Then, make
7294// low memory notification and ensure the socket pool is NOT flushed.
7295TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7296 HttpRequestInfo request;
7297 request.method = "GET";
7298 request.url = GURL("http://www.example.org/");
7299 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107300 request.traffic_annotation =
7301 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557302
7303 // Disable idle socket closing on memory pressure.
7304 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7306
7307 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7308
7309 MockRead data_reads[] = {
7310 // A part of the response body is received with the response headers.
7311 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7312 // The rest of the response body is received in two parts.
7313 MockRead("lo"), MockRead(" world"),
7314 MockRead("junk"), // Should not be read!!
7315 MockRead(SYNCHRONOUS, OK),
7316 };
7317
7318 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7319 session_deps_.socket_factory->AddSocketDataProvider(&data);
7320
7321 TestCompletionCallback callback;
7322
7323 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7325
7326 EXPECT_THAT(callback.GetResult(rv), IsOk());
7327
7328 const HttpResponseInfo* response = trans.GetResponseInfo();
7329 ASSERT_TRUE(response);
7330 EXPECT_TRUE(response->headers);
7331 std::string status_line = response->headers->GetStatusLine();
7332 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7333
7334 // Make memory critical notification and ensure the transaction still has been
7335 // operating right.
7336 base::MemoryPressureListener::NotifyMemoryPressure(
7337 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7338 base::RunLoop().RunUntilIdle();
7339
7340 // Socket should not be flushed as long as it is not idle.
7341 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7342
7343 std::string response_data;
7344 rv = ReadTransaction(&trans, &response_data);
7345 EXPECT_THAT(rv, IsOk());
7346 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.
7350 base::RunLoop().RunUntilIdle();
7351
7352 // We now check to make sure the socket was added back to the pool.
7353 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7354
7355 // Idle sockets should NOT be flushed on moderate memory pressure.
7356 base::MemoryPressureListener::NotifyMemoryPressure(
7357 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7358 base::RunLoop().RunUntilIdle();
7359
7360 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7361
7362 // Idle sockets should NOT be flushed on critical memory pressure.
7363 base::MemoryPressureListener::NotifyMemoryPressure(
7364 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7365 base::RunLoop().RunUntilIdle();
7366
7367 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7368}
7369
maksim.sisov0adf8592016-07-15 06:25:567370// Grab an SSL socket, use it, and put it back into the pool. Then, make
7371// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017372TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567373 HttpRequestInfo request;
7374 request.method = "GET";
7375 request.url = GURL("https://www.example.org/");
7376 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107377 request.traffic_annotation =
7378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567379
7380 MockWrite data_writes[] = {
7381 MockWrite("GET / HTTP/1.1\r\n"
7382 "Host: www.example.org\r\n"
7383 "Connection: keep-alive\r\n\r\n"),
7384 };
7385
7386 MockRead data_reads[] = {
7387 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7388 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7389
7390 SSLSocketDataProvider ssl(ASYNC, OK);
7391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7392
7393 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7394 arraysize(data_writes));
7395 session_deps_.socket_factory->AddSocketDataProvider(&data);
7396
7397 TestCompletionCallback callback;
7398
7399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567401
7402 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207403 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567404
7405 EXPECT_THAT(callback.GetResult(rv), IsOk());
7406
bnc691fda62016-08-12 00:43:167407 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567408 ASSERT_TRUE(response);
7409 ASSERT_TRUE(response->headers);
7410 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7411
7412 // Make memory critical notification and ensure the transaction still has been
7413 // operating right.
7414 base::MemoryPressureListener::NotifyMemoryPressure(
7415 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7416 base::RunLoop().RunUntilIdle();
7417
7418 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7419
7420 std::string response_data;
bnc691fda62016-08-12 00:43:167421 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567422 EXPECT_THAT(rv, IsOk());
7423 EXPECT_EQ("hello world", response_data);
7424
7425 // Empty the current queue. This is necessary because idle sockets are
7426 // added to the connection pool asynchronously with a PostTask.
7427 base::RunLoop().RunUntilIdle();
7428
7429 // We now check to make sure the socket was added back to the pool.
7430 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7431
7432 // Make memory notification once again and ensure idle socket is closed.
7433 base::MemoryPressureListener::NotifyMemoryPressure(
7434 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7435 base::RunLoop().RunUntilIdle();
7436
7437 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7438}
7439
[email protected]b4404c02009-04-10 16:38:527440// Make sure that we recycle a socket after a zero-length response.
7441// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017442TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427443 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527444 request.method = "GET";
bncce36dca22015-04-21 22:11:237445 request.url = GURL(
7446 "http://www.example.org/csi?v=3&s=web&action=&"
7447 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7448 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7449 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:107450 request.traffic_annotation =
7451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527452
danakj1fd259a02016-04-16 03:17:097453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277454
[email protected]b4404c02009-04-10 16:38:527455 MockRead data_reads[] = {
7456 MockRead("HTTP/1.1 204 No Content\r\n"
7457 "Content-Length: 0\r\n"
7458 "Content-Type: text/html\r\n\r\n"),
7459 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067460 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527461 };
7462
[email protected]31a2bfe2010-02-09 08:03:397463 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077464 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527465
mmenkecc2298e2015-12-07 18:20:187466 // Transaction must be created after the MockReads, so it's destroyed before
7467 // them.
bnc691fda62016-08-12 00:43:167468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187469
[email protected]49639fa2011-12-20 23:22:417470 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527471
tfarina42834112016-09-22 13:38:207472 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527474
7475 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017476 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527477
bnc691fda62016-08-12 00:43:167478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527479 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527480
wezca1070932016-05-26 20:30:527481 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527482 std::string status_line = response->headers->GetStatusLine();
7483 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7484
[email protected]90499482013-06-01 00:39:507485 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527486
7487 std::string response_data;
bnc691fda62016-08-12 00:43:167488 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017489 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527490 EXPECT_EQ("", response_data);
7491
7492 // Empty the current queue. This is necessary because idle sockets are
7493 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557494 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527495
7496 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507497 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527498}
7499
bncd16676a2016-07-20 16:23:017500TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097501 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227502 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197503 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227504 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277505
[email protected]1c773ea12009-04-28 19:58:427506 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517507 // Transaction 1: a GET request that succeeds. The socket is recycled
7508 // after use.
7509 request[0].method = "GET";
7510 request[0].url = GURL("http://www.google.com/");
7511 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107512 request[0].traffic_annotation =
7513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517514 // Transaction 2: a POST request. Reuses the socket kept alive from
7515 // transaction 1. The first attempts fails when writing the POST data.
7516 // This causes the transaction to retry with a new socket. The second
7517 // attempt succeeds.
7518 request[1].method = "POST";
7519 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277520 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517521 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107522 request[1].traffic_annotation =
7523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517524
danakj1fd259a02016-04-16 03:17:097525 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517526
7527 // The first socket is used for transaction 1 and the first attempt of
7528 // transaction 2.
7529
7530 // The response of transaction 1.
7531 MockRead data_reads1[] = {
7532 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7533 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067534 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517535 };
7536 // The mock write results of transaction 1 and the first attempt of
7537 // transaction 2.
7538 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067539 MockWrite(SYNCHRONOUS, 64), // GET
7540 MockWrite(SYNCHRONOUS, 93), // POST
7541 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517542 };
[email protected]31a2bfe2010-02-09 08:03:397543 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7544 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517545
7546 // The second socket is used for the second attempt of transaction 2.
7547
7548 // The response of transaction 2.
7549 MockRead data_reads2[] = {
7550 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7551 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067552 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517553 };
7554 // The mock write results of the second attempt of transaction 2.
7555 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067556 MockWrite(SYNCHRONOUS, 93), // POST
7557 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517558 };
[email protected]31a2bfe2010-02-09 08:03:397559 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7560 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517561
[email protected]bb88e1d32013-05-03 23:11:077562 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7563 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517564
thestig9d3bb0c2015-01-24 00:49:517565 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517566 "hello world", "welcome"
7567 };
7568
7569 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517571
[email protected]49639fa2011-12-20 23:22:417572 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517573
tfarina42834112016-09-22 13:38:207574 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517576
7577 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017578 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517579
bnc691fda62016-08-12 00:43:167580 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527581 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517582
wezca1070932016-05-26 20:30:527583 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517584 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7585
7586 std::string response_data;
bnc691fda62016-08-12 00:43:167587 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017588 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517589 EXPECT_EQ(kExpectedResponseData[i], response_data);
7590 }
7591}
[email protected]f9ee6b52008-11-08 06:46:237592
7593// Test the request-challenge-retry sequence for basic auth when there is
7594// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167595// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017596TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427597 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237598 request.method = "GET";
bncce36dca22015-04-21 22:11:237599 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417600 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107601 request.traffic_annotation =
7602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297603
danakj1fd259a02016-04-16 03:17:097604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167605 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277606
[email protected]a97cca42009-08-14 01:00:297607 // The password contains an escaped character -- for this test to pass it
7608 // will need to be unescaped by HttpNetworkTransaction.
7609 EXPECT_EQ("b%40r", request.url.password());
7610
[email protected]f9ee6b52008-11-08 06:46:237611 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237612 MockWrite(
7613 "GET / HTTP/1.1\r\n"
7614 "Host: www.example.org\r\n"
7615 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237616 };
7617
7618 MockRead data_reads1[] = {
7619 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7620 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7621 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067622 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237623 };
7624
[email protected]2262e3a2012-05-22 16:08:167625 // After the challenge above, the transaction will be restarted using the
7626 // identity from the url (foo, b@r) to answer the challenge.
7627 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237628 MockWrite(
7629 "GET / HTTP/1.1\r\n"
7630 "Host: www.example.org\r\n"
7631 "Connection: keep-alive\r\n"
7632 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167633 };
7634
7635 MockRead data_reads2[] = {
7636 MockRead("HTTP/1.0 200 OK\r\n"),
7637 MockRead("Content-Length: 100\r\n\r\n"),
7638 MockRead(SYNCHRONOUS, OK),
7639 };
7640
[email protected]31a2bfe2010-02-09 08:03:397641 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7642 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167643 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7644 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7646 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237647
[email protected]49639fa2011-12-20 23:22:417648 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207649 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237651 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017652 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167653 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167654
7655 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167656 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167658 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017659 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167660 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227661
bnc691fda62016-08-12 00:43:167662 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527663 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167664
7665 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527666 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167667
7668 EXPECT_EQ(100, response->headers->GetContentLength());
7669
7670 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557671 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167672}
7673
7674// Test the request-challenge-retry sequence for basic auth when there is an
7675// incorrect identity in the URL. The identity from the URL should be used only
7676// once.
bncd16676a2016-07-20 16:23:017677TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167678 HttpRequestInfo request;
7679 request.method = "GET";
7680 // Note: the URL has a username:password in it. The password "baz" is
7681 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237682 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167683
7684 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107685 request.traffic_annotation =
7686 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167687
danakj1fd259a02016-04-16 03:17:097688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167690
7691 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237692 MockWrite(
7693 "GET / HTTP/1.1\r\n"
7694 "Host: www.example.org\r\n"
7695 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167696 };
7697
7698 MockRead data_reads1[] = {
7699 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7700 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7701 MockRead("Content-Length: 10\r\n\r\n"),
7702 MockRead(SYNCHRONOUS, ERR_FAILED),
7703 };
7704
7705 // After the challenge above, the transaction will be restarted using the
7706 // identity from the url (foo, baz) to answer the challenge.
7707 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237708 MockWrite(
7709 "GET / HTTP/1.1\r\n"
7710 "Host: www.example.org\r\n"
7711 "Connection: keep-alive\r\n"
7712 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167713 };
7714
7715 MockRead data_reads2[] = {
7716 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7717 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7718 MockRead("Content-Length: 10\r\n\r\n"),
7719 MockRead(SYNCHRONOUS, ERR_FAILED),
7720 };
7721
7722 // After the challenge above, the transaction will be restarted using the
7723 // identity supplied by the user (foo, bar) to answer the challenge.
7724 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237725 MockWrite(
7726 "GET / HTTP/1.1\r\n"
7727 "Host: www.example.org\r\n"
7728 "Connection: keep-alive\r\n"
7729 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167730 };
7731
7732 MockRead data_reads3[] = {
7733 MockRead("HTTP/1.0 200 OK\r\n"),
7734 MockRead("Content-Length: 100\r\n\r\n"),
7735 MockRead(SYNCHRONOUS, OK),
7736 };
7737
7738 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7739 data_writes1, arraysize(data_writes1));
7740 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7741 data_writes2, arraysize(data_writes2));
7742 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7743 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077744 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7745 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7746 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167747
7748 TestCompletionCallback callback1;
7749
tfarina42834112016-09-22 13:38:207750 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167752
7753 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017754 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167755
bnc691fda62016-08-12 00:43:167756 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167757 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167758 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167760 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017761 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167762 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167763
bnc691fda62016-08-12 00:43:167764 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527765 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167766 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7767
7768 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167769 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167771 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017772 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167773 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167774
bnc691fda62016-08-12 00:43:167775 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527776 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167777
7778 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527779 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167780
7781 EXPECT_EQ(100, response->headers->GetContentLength());
7782
[email protected]ea9dc9a2009-09-05 00:43:327783 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557784 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327785}
7786
[email protected]2217aa22013-10-11 03:03:547787
7788// Test the request-challenge-retry sequence for basic auth when there is a
7789// correct identity in the URL, but its use is being suppressed. The identity
7790// from the URL should never be used.
bncd16676a2016-07-20 16:23:017791TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547792 HttpRequestInfo request;
7793 request.method = "GET";
bncce36dca22015-04-21 22:11:237794 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547795 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:107796 request.traffic_annotation =
7797 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547798
danakj1fd259a02016-04-16 03:17:097799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547801
7802 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237803 MockWrite(
7804 "GET / HTTP/1.1\r\n"
7805 "Host: www.example.org\r\n"
7806 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547807 };
7808
7809 MockRead data_reads1[] = {
7810 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7811 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7812 MockRead("Content-Length: 10\r\n\r\n"),
7813 MockRead(SYNCHRONOUS, ERR_FAILED),
7814 };
7815
7816 // After the challenge above, the transaction will be restarted using the
7817 // identity supplied by the user, not the one in the URL, to answer the
7818 // challenge.
7819 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237820 MockWrite(
7821 "GET / HTTP/1.1\r\n"
7822 "Host: www.example.org\r\n"
7823 "Connection: keep-alive\r\n"
7824 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547825 };
7826
7827 MockRead data_reads3[] = {
7828 MockRead("HTTP/1.0 200 OK\r\n"),
7829 MockRead("Content-Length: 100\r\n\r\n"),
7830 MockRead(SYNCHRONOUS, OK),
7831 };
7832
7833 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7834 data_writes1, arraysize(data_writes1));
7835 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7836 data_writes3, arraysize(data_writes3));
7837 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7838 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7839
7840 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207841 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547843 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017844 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167845 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547846
bnc691fda62016-08-12 00:43:167847 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527848 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547849 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7850
7851 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167852 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547854 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017855 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167856 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547857
bnc691fda62016-08-12 00:43:167858 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527859 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547860
7861 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527862 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547863 EXPECT_EQ(100, response->headers->GetContentLength());
7864
7865 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557866 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547867}
7868
[email protected]f9ee6b52008-11-08 06:46:237869// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017870TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097871 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237872
7873 // Transaction 1: authenticate (foo, bar) on MyRealm1
7874 {
[email protected]1c773ea12009-04-28 19:58:427875 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237876 request.method = "GET";
bncce36dca22015-04-21 22:11:237877 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:107878 request.traffic_annotation =
7879 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237880
bnc691fda62016-08-12 00:43:167881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277882
[email protected]f9ee6b52008-11-08 06:46:237883 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237884 MockWrite(
7885 "GET /x/y/z HTTP/1.1\r\n"
7886 "Host: www.example.org\r\n"
7887 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237888 };
7889
7890 MockRead data_reads1[] = {
7891 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7892 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7893 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067894 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237895 };
7896
7897 // Resend with authorization (username=foo, password=bar)
7898 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237899 MockWrite(
7900 "GET /x/y/z HTTP/1.1\r\n"
7901 "Host: www.example.org\r\n"
7902 "Connection: keep-alive\r\n"
7903 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237904 };
7905
7906 // Sever accepts the authorization.
7907 MockRead data_reads2[] = {
7908 MockRead("HTTP/1.0 200 OK\r\n"),
7909 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067910 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237911 };
7912
[email protected]31a2bfe2010-02-09 08:03:397913 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7914 data_writes1, arraysize(data_writes1));
7915 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7916 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077917 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7918 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237919
[email protected]49639fa2011-12-20 23:22:417920 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237921
tfarina42834112016-09-22 13:38:207922 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237924
7925 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017926 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237927
bnc691fda62016-08-12 00:43:167928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527929 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047930 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237931
[email protected]49639fa2011-12-20 23:22:417932 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237933
bnc691fda62016-08-12 00:43:167934 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7935 callback2.callback());
robpercival214763f2016-07-01 23:27:017936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237937
7938 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017939 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237940
bnc691fda62016-08-12 00:43:167941 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527942 ASSERT_TRUE(response);
7943 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237944 EXPECT_EQ(100, response->headers->GetContentLength());
7945 }
7946
7947 // ------------------------------------------------------------------------
7948
7949 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7950 {
[email protected]1c773ea12009-04-28 19:58:427951 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237952 request.method = "GET";
7953 // Note that Transaction 1 was at /x/y/z, so this is in the same
7954 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237955 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:107956 request.traffic_annotation =
7957 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237958
bnc691fda62016-08-12 00:43:167959 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277960
[email protected]f9ee6b52008-11-08 06:46:237961 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237962 MockWrite(
7963 "GET /x/y/a/b HTTP/1.1\r\n"
7964 "Host: www.example.org\r\n"
7965 "Connection: keep-alive\r\n"
7966 // Send preemptive authorization for MyRealm1
7967 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237968 };
7969
7970 // The server didn't like the preemptive authorization, and
7971 // challenges us for a different realm (MyRealm2).
7972 MockRead data_reads1[] = {
7973 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7974 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7975 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067976 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237977 };
7978
7979 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7980 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237981 MockWrite(
7982 "GET /x/y/a/b HTTP/1.1\r\n"
7983 "Host: www.example.org\r\n"
7984 "Connection: keep-alive\r\n"
7985 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237986 };
7987
7988 // Sever accepts the authorization.
7989 MockRead data_reads2[] = {
7990 MockRead("HTTP/1.0 200 OK\r\n"),
7991 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067992 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237993 };
7994
[email protected]31a2bfe2010-02-09 08:03:397995 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7996 data_writes1, arraysize(data_writes1));
7997 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7998 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077999 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8000 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238001
[email protected]49639fa2011-12-20 23:22:418002 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238003
tfarina42834112016-09-22 13:38:208004 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238006
8007 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018008 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238009
bnc691fda62016-08-12 00:43:168010 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528011 ASSERT_TRUE(response);
8012 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048013 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438014 EXPECT_EQ("http://www.example.org",
8015 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048016 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198017 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238018
[email protected]49639fa2011-12-20 23:22:418019 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238020
bnc691fda62016-08-12 00:43:168021 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8022 callback2.callback());
robpercival214763f2016-07-01 23:27:018023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238024
8025 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018026 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238027
bnc691fda62016-08-12 00:43:168028 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528029 ASSERT_TRUE(response);
8030 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238031 EXPECT_EQ(100, response->headers->GetContentLength());
8032 }
8033
8034 // ------------------------------------------------------------------------
8035
8036 // Transaction 3: Resend a request in MyRealm's protection space --
8037 // succeed with preemptive authorization.
8038 {
[email protected]1c773ea12009-04-28 19:58:428039 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238040 request.method = "GET";
bncce36dca22015-04-21 22:11:238041 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108042 request.traffic_annotation =
8043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238044
bnc691fda62016-08-12 00:43:168045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278046
[email protected]f9ee6b52008-11-08 06:46:238047 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238048 MockWrite(
8049 "GET /x/y/z2 HTTP/1.1\r\n"
8050 "Host: www.example.org\r\n"
8051 "Connection: keep-alive\r\n"
8052 // The authorization for MyRealm1 gets sent preemptively
8053 // (since the url is in the same protection space)
8054 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238055 };
8056
8057 // Sever accepts the preemptive authorization
8058 MockRead data_reads1[] = {
8059 MockRead("HTTP/1.0 200 OK\r\n"),
8060 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068061 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238062 };
8063
[email protected]31a2bfe2010-02-09 08:03:398064 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8065 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078066 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238067
[email protected]49639fa2011-12-20 23:22:418068 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238069
tfarina42834112016-09-22 13:38:208070 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238072
8073 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018074 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238075
bnc691fda62016-08-12 00:43:168076 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528077 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238078
wezca1070932016-05-26 20:30:528079 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238080 EXPECT_EQ(100, response->headers->GetContentLength());
8081 }
8082
8083 // ------------------------------------------------------------------------
8084
8085 // Transaction 4: request another URL in MyRealm (however the
8086 // url is not known to belong to the protection space, so no pre-auth).
8087 {
[email protected]1c773ea12009-04-28 19:58:428088 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238089 request.method = "GET";
bncce36dca22015-04-21 22:11:238090 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108091 request.traffic_annotation =
8092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238093
bnc691fda62016-08-12 00:43:168094 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278095
[email protected]f9ee6b52008-11-08 06:46:238096 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238097 MockWrite(
8098 "GET /x/1 HTTP/1.1\r\n"
8099 "Host: www.example.org\r\n"
8100 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238101 };
8102
8103 MockRead data_reads1[] = {
8104 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8105 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8106 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068107 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238108 };
8109
8110 // Resend with authorization from MyRealm's cache.
8111 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238112 MockWrite(
8113 "GET /x/1 HTTP/1.1\r\n"
8114 "Host: www.example.org\r\n"
8115 "Connection: keep-alive\r\n"
8116 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238117 };
8118
8119 // Sever accepts the authorization.
8120 MockRead data_reads2[] = {
8121 MockRead("HTTP/1.0 200 OK\r\n"),
8122 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068123 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238124 };
8125
[email protected]31a2bfe2010-02-09 08:03:398126 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8127 data_writes1, arraysize(data_writes1));
8128 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8129 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078130 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8131 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238132
[email protected]49639fa2011-12-20 23:22:418133 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238134
tfarina42834112016-09-22 13:38:208135 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238137
8138 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018139 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238140
bnc691fda62016-08-12 00:43:168141 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418142 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168143 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018144 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228145 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018146 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168147 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228148
bnc691fda62016-08-12 00:43:168149 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528150 ASSERT_TRUE(response);
8151 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238152 EXPECT_EQ(100, response->headers->GetContentLength());
8153 }
8154
8155 // ------------------------------------------------------------------------
8156
8157 // Transaction 5: request a URL in MyRealm, but the server rejects the
8158 // cached identity. Should invalidate and re-prompt.
8159 {
[email protected]1c773ea12009-04-28 19:58:428160 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238161 request.method = "GET";
bncce36dca22015-04-21 22:11:238162 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:108163 request.traffic_annotation =
8164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238165
bnc691fda62016-08-12 00:43:168166 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278167
[email protected]f9ee6b52008-11-08 06:46:238168 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238169 MockWrite(
8170 "GET /p/q/t HTTP/1.1\r\n"
8171 "Host: www.example.org\r\n"
8172 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238173 };
8174
8175 MockRead data_reads1[] = {
8176 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8177 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8178 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068179 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238180 };
8181
8182 // Resend with authorization from cache for MyRealm.
8183 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238184 MockWrite(
8185 "GET /p/q/t HTTP/1.1\r\n"
8186 "Host: www.example.org\r\n"
8187 "Connection: keep-alive\r\n"
8188 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238189 };
8190
8191 // Sever rejects the authorization.
8192 MockRead data_reads2[] = {
8193 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8194 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8195 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068196 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238197 };
8198
8199 // At this point we should prompt for new credentials for MyRealm.
8200 // Restart with username=foo3, password=foo4.
8201 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238202 MockWrite(
8203 "GET /p/q/t HTTP/1.1\r\n"
8204 "Host: www.example.org\r\n"
8205 "Connection: keep-alive\r\n"
8206 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238207 };
8208
8209 // Sever accepts the authorization.
8210 MockRead data_reads3[] = {
8211 MockRead("HTTP/1.0 200 OK\r\n"),
8212 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068213 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238214 };
8215
[email protected]31a2bfe2010-02-09 08:03:398216 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8217 data_writes1, arraysize(data_writes1));
8218 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8219 data_writes2, arraysize(data_writes2));
8220 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8221 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078222 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8223 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8224 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238225
[email protected]49639fa2011-12-20 23:22:418226 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238227
tfarina42834112016-09-22 13:38:208228 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238230
8231 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018232 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238233
bnc691fda62016-08-12 00:43:168234 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418235 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168236 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018237 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228238 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018239 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168240 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228241
bnc691fda62016-08-12 00:43:168242 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528243 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048244 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238245
[email protected]49639fa2011-12-20 23:22:418246 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238247
bnc691fda62016-08-12 00:43:168248 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8249 callback3.callback());
robpercival214763f2016-07-01 23:27:018250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238251
[email protected]0757e7702009-03-27 04:00:228252 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018253 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238254
bnc691fda62016-08-12 00:43:168255 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528256 ASSERT_TRUE(response);
8257 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238258 EXPECT_EQ(100, response->headers->GetContentLength());
8259 }
8260}
[email protected]89ceba9a2009-03-21 03:46:068261
[email protected]3c32c5f2010-05-18 15:18:128262// Tests that nonce count increments when multiple auth attempts
8263// are started with the same nonce.
bncd16676a2016-07-20 16:23:018264TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448265 HttpAuthHandlerDigest::Factory* digest_factory =
8266 new HttpAuthHandlerDigest::Factory();
8267 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8268 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8269 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078270 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128272
8273 // Transaction 1: authenticate (foo, bar) on MyRealm1
8274 {
[email protected]3c32c5f2010-05-18 15:18:128275 HttpRequestInfo request;
8276 request.method = "GET";
bncce36dca22015-04-21 22:11:238277 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108278 request.traffic_annotation =
8279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128280
bnc691fda62016-08-12 00:43:168281 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278282
[email protected]3c32c5f2010-05-18 15:18:128283 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238284 MockWrite(
8285 "GET /x/y/z HTTP/1.1\r\n"
8286 "Host: www.example.org\r\n"
8287 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128288 };
8289
8290 MockRead data_reads1[] = {
8291 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8292 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8293 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068294 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128295 };
8296
8297 // Resend with authorization (username=foo, password=bar)
8298 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238299 MockWrite(
8300 "GET /x/y/z HTTP/1.1\r\n"
8301 "Host: www.example.org\r\n"
8302 "Connection: keep-alive\r\n"
8303 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8304 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8305 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8306 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128307 };
8308
8309 // Sever accepts the authorization.
8310 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088311 MockRead("HTTP/1.0 200 OK\r\n"),
8312 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128313 };
8314
8315 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8316 data_writes1, arraysize(data_writes1));
8317 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8318 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078319 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8320 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128321
[email protected]49639fa2011-12-20 23:22:418322 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128323
tfarina42834112016-09-22 13:38:208324 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128326
8327 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018328 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128329
bnc691fda62016-08-12 00:43:168330 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528331 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048332 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128333
[email protected]49639fa2011-12-20 23:22:418334 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128335
bnc691fda62016-08-12 00:43:168336 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8337 callback2.callback());
robpercival214763f2016-07-01 23:27:018338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128339
8340 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018341 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128342
bnc691fda62016-08-12 00:43:168343 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528344 ASSERT_TRUE(response);
8345 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128346 }
8347
8348 // ------------------------------------------------------------------------
8349
8350 // Transaction 2: Request another resource in digestive's protection space.
8351 // This will preemptively add an Authorization header which should have an
8352 // "nc" value of 2 (as compared to 1 in the first use.
8353 {
[email protected]3c32c5f2010-05-18 15:18:128354 HttpRequestInfo request;
8355 request.method = "GET";
8356 // Note that Transaction 1 was at /x/y/z, so this is in the same
8357 // protection space as digest.
bncce36dca22015-04-21 22:11:238358 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108359 request.traffic_annotation =
8360 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128361
bnc691fda62016-08-12 00:43:168362 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278363
[email protected]3c32c5f2010-05-18 15:18:128364 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238365 MockWrite(
8366 "GET /x/y/a/b HTTP/1.1\r\n"
8367 "Host: www.example.org\r\n"
8368 "Connection: keep-alive\r\n"
8369 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8370 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8371 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8372 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128373 };
8374
8375 // Sever accepts the authorization.
8376 MockRead data_reads1[] = {
8377 MockRead("HTTP/1.0 200 OK\r\n"),
8378 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068379 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128380 };
8381
8382 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8383 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078384 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128385
[email protected]49639fa2011-12-20 23:22:418386 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128387
tfarina42834112016-09-22 13:38:208388 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128390
8391 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018392 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128393
bnc691fda62016-08-12 00:43:168394 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528395 ASSERT_TRUE(response);
8396 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128397 }
8398}
8399
[email protected]89ceba9a2009-03-21 03:46:068400// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018401TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068402 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168404 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068405
8406 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168407 trans.read_buf_ = new IOBuffer(15);
8408 trans.read_buf_len_ = 15;
8409 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068410
8411 // Setup state in response_
bnc691fda62016-08-12 00:43:168412 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578413 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088414 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578415 response->response_time = base::Time::Now();
8416 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068417
8418 { // Setup state for response_.vary_data
8419 HttpRequestInfo request;
8420 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8421 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278422 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438423 request.extra_headers.SetHeader("Foo", "1");
8424 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508425 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068426 }
8427
8428 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168429 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068430
8431 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168432 EXPECT_FALSE(trans.read_buf_);
8433 EXPECT_EQ(0, trans.read_buf_len_);
8434 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528435 EXPECT_FALSE(response->auth_challenge);
8436 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048437 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088438 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578439 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068440}
8441
[email protected]bacff652009-03-31 17:50:338442// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018443TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338444 HttpRequestInfo request;
8445 request.method = "GET";
bncce36dca22015-04-21 22:11:238446 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108447 request.traffic_annotation =
8448 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338449
danakj1fd259a02016-04-16 03:17:098450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278452
[email protected]bacff652009-03-31 17:50:338453 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238454 MockWrite(
8455 "GET / HTTP/1.1\r\n"
8456 "Host: www.example.org\r\n"
8457 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338458 };
8459
8460 MockRead data_reads[] = {
8461 MockRead("HTTP/1.0 200 OK\r\n"),
8462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8463 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068464 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338465 };
8466
[email protected]5ecc992a42009-11-11 01:41:598467 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398468 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8469 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068470 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8471 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338472
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8474 session_deps_.socket_factory->AddSocketDataProvider(&data);
8475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338477
[email protected]49639fa2011-12-20 23:22:418478 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338479
tfarina42834112016-09-22 13:38:208480 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338482
8483 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018484 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338485
bnc691fda62016-08-12 00:43:168486 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338488
8489 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018490 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338491
bnc691fda62016-08-12 00:43:168492 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338493
wezca1070932016-05-26 20:30:528494 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338495 EXPECT_EQ(100, response->headers->GetContentLength());
8496}
8497
8498// Test HTTPS connections to a site with a bad certificate, going through a
8499// proxy
bncd16676a2016-07-20 16:23:018500TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498501 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8502 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338503
8504 HttpRequestInfo request;
8505 request.method = "GET";
bncce36dca22015-04-21 22:11:238506 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108507 request.traffic_annotation =
8508 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338509
8510 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178511 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8512 "Host: www.example.org:443\r\n"
8513 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338514 };
8515
8516 MockRead proxy_reads[] = {
8517 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068518 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338519 };
8520
8521 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178522 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8523 "Host: www.example.org:443\r\n"
8524 "Proxy-Connection: keep-alive\r\n\r\n"),
8525 MockWrite("GET / HTTP/1.1\r\n"
8526 "Host: www.example.org\r\n"
8527 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338528 };
8529
8530 MockRead data_reads[] = {
8531 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8532 MockRead("HTTP/1.0 200 OK\r\n"),
8533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8534 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068535 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338536 };
8537
[email protected]31a2bfe2010-02-09 08:03:398538 StaticSocketDataProvider ssl_bad_certificate(
8539 proxy_reads, arraysize(proxy_reads),
8540 proxy_writes, arraysize(proxy_writes));
8541 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8542 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068543 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8544 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338545
[email protected]bb88e1d32013-05-03 23:11:078546 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8547 session_deps_.socket_factory->AddSocketDataProvider(&data);
8548 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8549 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338550
[email protected]49639fa2011-12-20 23:22:418551 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338552
8553 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078554 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338555
danakj1fd259a02016-04-16 03:17:098556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168557 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338558
tfarina42834112016-09-22 13:38:208559 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338561
8562 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018563 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338564
bnc691fda62016-08-12 00:43:168565 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338567
8568 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018569 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338570
bnc691fda62016-08-12 00:43:168571 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338572
wezca1070932016-05-26 20:30:528573 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338574 EXPECT_EQ(100, response->headers->GetContentLength());
8575 }
8576}
8577
[email protected]2df19bb2010-08-25 20:13:468578
8579// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018580TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598581 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498582 ProxyResolutionService::CreateFixedFromPacResult(
8583 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518584 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078585 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468586
8587 HttpRequestInfo request;
8588 request.method = "GET";
bncce36dca22015-04-21 22:11:238589 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108590 request.traffic_annotation =
8591 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468592
8593 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178594 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8595 "Host: www.example.org:443\r\n"
8596 "Proxy-Connection: keep-alive\r\n\r\n"),
8597 MockWrite("GET / HTTP/1.1\r\n"
8598 "Host: www.example.org\r\n"
8599 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468600 };
8601
8602 MockRead data_reads[] = {
8603 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8604 MockRead("HTTP/1.1 200 OK\r\n"),
8605 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8606 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068607 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468608 };
8609
8610 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8611 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068612 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8613 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468614
[email protected]bb88e1d32013-05-03 23:11:078615 session_deps_.socket_factory->AddSocketDataProvider(&data);
8616 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8617 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468618
[email protected]49639fa2011-12-20 23:22:418619 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468620
danakj1fd259a02016-04-16 03:17:098621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168622 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468623
tfarina42834112016-09-22 13:38:208624 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468626
8627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018628 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168629 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468630
wezca1070932016-05-26 20:30:528631 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468632
tbansal2ecbbc72016-10-06 17:15:478633 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468634 EXPECT_TRUE(response->headers->IsKeepAlive());
8635 EXPECT_EQ(200, response->headers->response_code());
8636 EXPECT_EQ(100, response->headers->GetContentLength());
8637 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208638
8639 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168640 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208641 TestLoadTimingNotReusedWithPac(load_timing_info,
8642 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468643}
8644
[email protected]511f6f52010-12-17 03:58:298645// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018646TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598647 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498648 ProxyResolutionService::CreateFixedFromPacResult(
8649 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518650 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078651 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298652
8653 HttpRequestInfo request;
8654 request.method = "GET";
bncce36dca22015-04-21 22:11:238655 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108656 request.traffic_annotation =
8657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298658
8659 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178660 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8661 "Host: www.example.org:443\r\n"
8662 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298663 };
8664
8665 MockRead data_reads[] = {
8666 MockRead("HTTP/1.1 302 Redirect\r\n"),
8667 MockRead("Location: http://login.example.com/\r\n"),
8668 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068669 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298670 };
8671
8672 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8673 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068674 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298675
[email protected]bb88e1d32013-05-03 23:11:078676 session_deps_.socket_factory->AddSocketDataProvider(&data);
8677 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298678
[email protected]49639fa2011-12-20 23:22:418679 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298680
danakj1fd259a02016-04-16 03:17:098681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168682 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298683
tfarina42834112016-09-22 13:38:208684 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298686
8687 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018688 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168689 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298690
wezca1070932016-05-26 20:30:528691 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298692
8693 EXPECT_EQ(302, response->headers->response_code());
8694 std::string url;
8695 EXPECT_TRUE(response->headers->IsRedirect(&url));
8696 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208697
8698 // In the case of redirects from proxies, HttpNetworkTransaction returns
8699 // timing for the proxy connection instead of the connection to the host,
8700 // and no send / receive times.
8701 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8702 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168703 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208704
8705 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198706 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208707
8708 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8709 EXPECT_LE(load_timing_info.proxy_resolve_start,
8710 load_timing_info.proxy_resolve_end);
8711 EXPECT_LE(load_timing_info.proxy_resolve_end,
8712 load_timing_info.connect_timing.connect_start);
8713 ExpectConnectTimingHasTimes(
8714 load_timing_info.connect_timing,
8715 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8716
8717 EXPECT_TRUE(load_timing_info.send_start.is_null());
8718 EXPECT_TRUE(load_timing_info.send_end.is_null());
8719 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298720}
8721
8722// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018723TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498724 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8725 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298726
8727 HttpRequestInfo request;
8728 request.method = "GET";
bncce36dca22015-04-21 22:11:238729 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108730 request.traffic_annotation =
8731 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298732
bncdf80d44fd2016-07-15 20:27:418733 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238734 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418735 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088736 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298737 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418738 CreateMockWrite(conn, 0, SYNCHRONOUS),
8739 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298740 };
8741
8742 static const char* const kExtraHeaders[] = {
8743 "location",
8744 "http://login.example.com/",
8745 };
bnc42331402016-07-25 13:36:158746 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238747 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298748 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418749 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298750 };
8751
rch8e6c6c42015-05-01 14:05:138752 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8753 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068754 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368755 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298756
[email protected]bb88e1d32013-05-03 23:11:078757 session_deps_.socket_factory->AddSocketDataProvider(&data);
8758 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298759
[email protected]49639fa2011-12-20 23:22:418760 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298761
danakj1fd259a02016-04-16 03:17:098762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168763 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298764
tfarina42834112016-09-22 13:38:208765 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018766 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298767
8768 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018769 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168770 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298771
wezca1070932016-05-26 20:30:528772 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298773
8774 EXPECT_EQ(302, response->headers->response_code());
8775 std::string url;
8776 EXPECT_TRUE(response->headers->IsRedirect(&url));
8777 EXPECT_EQ("http://login.example.com/", url);
8778}
8779
[email protected]4eddbc732012-08-09 05:40:178780// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018781TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498782 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8783 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[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 Halavatib5e433e62018-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 404 Not Found\r\n"),
8799 MockRead("Content-Length: 23\r\n\r\n"),
8800 MockRead("The host does not exist"),
[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, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298821
ttuttle960fcbf2016-04-19 13:26:328822 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298823}
8824
[email protected]4eddbc732012-08-09 05:40:178825// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018826TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498827 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8828 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298829
8830 HttpRequestInfo request;
8831 request.method = "GET";
bncce36dca22015-04-21 22:11:238832 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108833 request.traffic_annotation =
8834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298835
bncdf80d44fd2016-07-15 20:27:418836 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238837 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418838 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088839 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298840 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418841 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298842 };
8843
8844 static const char* const kExtraHeaders[] = {
8845 "location",
8846 "http://login.example.com/",
8847 };
bnc42331402016-07-25 13:36:158848 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238849 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Bence Békyd74f4382018-02-20 18:26:198850 SpdySerializedFrame body(
8851 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298852 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418853 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138854 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298855 };
8856
rch8e6c6c42015-05-01 14:05:138857 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8858 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068859 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368860 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298861
[email protected]bb88e1d32013-05-03 23:11:078862 session_deps_.socket_factory->AddSocketDataProvider(&data);
8863 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298864
[email protected]49639fa2011-12-20 23:22:418865 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298866
danakj1fd259a02016-04-16 03:17:098867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168868 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298869
tfarina42834112016-09-22 13:38:208870 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298872
8873 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018874 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298875
ttuttle960fcbf2016-04-19 13:26:328876 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298877}
8878
[email protected]0c5fb722012-02-28 11:50:358879// Test the request-challenge-retry sequence for basic auth, through
8880// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018881TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358882 HttpRequestInfo request;
8883 request.method = "GET";
bncce36dca22015-04-21 22:11:238884 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358885 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298886 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:108887 request.traffic_annotation =
8888 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358889
8890 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598891 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498892 ProxyResolutionService::CreateFixedFromPacResult(
8893 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518894 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078895 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098896 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358897
8898 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418899 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238900 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418901 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088902 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388903 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358904
bnc691fda62016-08-12 00:43:168905 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358906 // be issuing -- the final header line contains the credentials.
8907 const char* const kAuthCredentials[] = {
8908 "proxy-authorization", "Basic Zm9vOmJhcg==",
8909 };
bncdf80d44fd2016-07-15 20:27:418910 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348911 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238912 HostPortPair("www.example.org", 443)));
8913 // fetch https://www.example.org/ via HTTP
8914 const char get[] =
8915 "GET / HTTP/1.1\r\n"
8916 "Host: www.example.org\r\n"
8917 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418918 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198919 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358920
8921 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418922 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8923 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358924 };
8925
8926 // The proxy responds to the connect with a 407, using a persistent
8927 // connection.
thestig9d3bb0c2015-01-24 00:49:518928 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358929 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358930 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8931 };
bnc42331402016-07-25 13:36:158932 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418933 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358934
bnc42331402016-07-25 13:36:158935 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358936 const char resp[] = "HTTP/1.1 200 OK\r\n"
8937 "Content-Length: 5\r\n\r\n";
8938
bncdf80d44fd2016-07-15 20:27:418939 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198940 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
bncdf80d44fd2016-07-15 20:27:418941 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198942 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358943 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418944 CreateMockRead(conn_auth_resp, 1, ASYNC),
8945 CreateMockRead(conn_resp, 4, ASYNC),
8946 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8947 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138948 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358949 };
8950
rch8e6c6c42015-05-01 14:05:138951 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8952 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078953 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358954 // Negotiate SPDY to the proxy
8955 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368956 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078957 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358958 // Vanilla SSL to the server
8959 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078960 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358961
8962 TestCompletionCallback callback1;
8963
bnc87dcefc2017-05-25 12:47:588964 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198965 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358966
8967 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358969
8970 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018971 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468972 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358973 log.GetEntries(&entries);
8974 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008975 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8976 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358977 ExpectLogContainsSomewhere(
8978 entries, pos,
mikecirone8b85c432016-09-08 19:11:008979 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8980 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358981
8982 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528983 ASSERT_TRUE(response);
8984 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358985 EXPECT_EQ(407, response->headers->response_code());
8986 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528987 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438988 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358989
8990 TestCompletionCallback callback2;
8991
8992 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8993 callback2.callback());
robpercival214763f2016-07-01 23:27:018994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358995
8996 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018997 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358998
8999 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529000 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359001
9002 EXPECT_TRUE(response->headers->IsKeepAlive());
9003 EXPECT_EQ(200, response->headers->response_code());
9004 EXPECT_EQ(5, response->headers->GetContentLength());
9005 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9006
9007 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529008 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359009
[email protected]029c83b62013-01-24 05:28:209010 LoadTimingInfo load_timing_info;
9011 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9012 TestLoadTimingNotReusedWithPac(load_timing_info,
9013 CONNECT_TIMING_HAS_SSL_TIMES);
9014
[email protected]0c5fb722012-02-28 11:50:359015 trans.reset();
9016 session->CloseAllConnections();
9017}
9018
[email protected]7c6f7ba2012-04-03 04:09:299019// Test that an explicitly trusted SPDY proxy can push a resource from an
9020// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019021TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159022 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199023 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159024 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9025 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299026 HttpRequestInfo request;
9027 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109028 request.traffic_annotation =
9029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299030
[email protected]7c6f7ba2012-04-03 04:09:299031 request.method = "GET";
bncce36dca22015-04-21 22:11:239032 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299033 push_request.method = "GET";
9034 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109035 push_request.traffic_annotation =
9036 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299037
tbansal28e68f82016-02-04 02:56:159038 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599039 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499040 ProxyResolutionService::CreateFixedFromPacResult(
9041 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519042 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079043 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509044
inlinechan894515af2016-12-09 02:40:109045 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509046
danakj1fd259a02016-04-16 03:17:099047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299048
bncdf80d44fd2016-07-15 20:27:419049 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459050 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359051 SpdySerializedFrame stream2_priority(
9052 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299053
9054 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419055 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359056 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299057 };
9058
Bence Béky7bf94362018-01-10 13:19:369059 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9060 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9061
bncdf80d44fd2016-07-15 20:27:419062 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159063 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299064
bncdf80d44fd2016-07-15 20:27:419065 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299066
Bence Békyd74f4382018-02-20 18:26:199067 SpdySerializedFrame stream2_body(
9068 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299069
9070 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369071 CreateMockRead(stream2_syn, 1, ASYNC),
9072 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359073 CreateMockRead(stream1_body, 4, ASYNC),
9074 CreateMockRead(stream2_body, 5, ASYNC),
9075 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299076 };
9077
rch8e6c6c42015-05-01 14:05:139078 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9079 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079080 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299081 // Negotiate SPDY to the proxy
9082 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369083 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079084 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299085
bnc87dcefc2017-05-25 12:47:589086 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199087 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299088 TestCompletionCallback callback;
9089 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299091
9092 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019093 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299094 const HttpResponseInfo* response = trans->GetResponseInfo();
9095
bnc87dcefc2017-05-25 12:47:589096 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199097 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509098 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299100
9101 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019102 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299103 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9104
wezca1070932016-05-26 20:30:529105 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299106 EXPECT_TRUE(response->headers->IsKeepAlive());
9107
9108 EXPECT_EQ(200, response->headers->response_code());
9109 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9110
9111 std::string response_data;
9112 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299114 EXPECT_EQ("hello!", response_data);
9115
[email protected]029c83b62013-01-24 05:28:209116 LoadTimingInfo load_timing_info;
9117 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9118 TestLoadTimingNotReusedWithPac(load_timing_info,
9119 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9120
[email protected]7c6f7ba2012-04-03 04:09:299121 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529122 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299123 EXPECT_EQ(200, push_response->headers->response_code());
9124
9125 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019126 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299127 EXPECT_EQ("pushed", response_data);
9128
[email protected]029c83b62013-01-24 05:28:209129 LoadTimingInfo push_load_timing_info;
9130 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9131 TestLoadTimingReusedWithPac(push_load_timing_info);
9132 // The transactions should share a socket ID, despite being for different
9133 // origins.
9134 EXPECT_EQ(load_timing_info.socket_log_id,
9135 push_load_timing_info.socket_log_id);
9136
[email protected]7c6f7ba2012-04-03 04:09:299137 trans.reset();
9138 push_trans.reset();
9139 session->CloseAllConnections();
9140}
9141
[email protected]8c843192012-04-05 07:15:009142// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019143TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159144 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199145 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159146 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9147 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009148 HttpRequestInfo request;
9149
9150 request.method = "GET";
bncce36dca22015-04-21 22:11:239151 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109152 request.traffic_annotation =
9153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009154
Ramin Halavatica8d5252018-03-12 05:33:499155 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9156 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519157 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079158 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509159
9160 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109161 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509162
danakj1fd259a02016-04-16 03:17:099163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009164
bncdf80d44fd2016-07-15 20:27:419165 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459166 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009167
bncdf80d44fd2016-07-15 20:27:419168 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089169 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009170
9171 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419172 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009173 };
9174
bncdf80d44fd2016-07-15 20:27:419175 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159176 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009177
bncdf80d44fd2016-07-15 20:27:419178 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009179
bncdf80d44fd2016-07-15 20:27:419180 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559181 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009182
9183 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419184 CreateMockRead(stream1_reply, 1, ASYNC),
9185 CreateMockRead(stream2_syn, 2, ASYNC),
9186 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599187 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009188 };
9189
rch8e6c6c42015-05-01 14:05:139190 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9191 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079192 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009193 // Negotiate SPDY to the proxy
9194 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369195 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079196 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009197
bnc87dcefc2017-05-25 12:47:589198 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199199 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009200 TestCompletionCallback callback;
9201 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009203
9204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019205 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009206 const HttpResponseInfo* response = trans->GetResponseInfo();
9207
wezca1070932016-05-26 20:30:529208 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009209 EXPECT_TRUE(response->headers->IsKeepAlive());
9210
9211 EXPECT_EQ(200, response->headers->response_code());
9212 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9213
9214 std::string response_data;
9215 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019216 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009217 EXPECT_EQ("hello!", response_data);
9218
9219 trans.reset();
9220 session->CloseAllConnections();
9221}
9222
tbansal8ef1d3e2016-02-03 04:05:429223// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9224// resources.
bncd16676a2016-07-20 16:23:019225TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159226 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199227 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159228 proxy_delegate->set_trusted_spdy_proxy(
9229 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9230
tbansal8ef1d3e2016-02-03 04:05:429231 HttpRequestInfo request;
9232
9233 request.method = "GET";
9234 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109235 request.traffic_annotation =
9236 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429237
9238 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499239 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9240 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429241 BoundTestNetLog log;
9242 session_deps_.net_log = log.bound().net_log();
9243
9244 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109245 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429246
danakj1fd259a02016-04-16 03:17:099247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429248
bncdf80d44fd2016-07-15 20:27:419249 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459250 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359251 SpdySerializedFrame stream2_priority(
9252 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429253
9254 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419255 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359256 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429257 };
9258
bncdf80d44fd2016-07-15 20:27:419259 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159260 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429261
bncdf80d44fd2016-07-15 20:27:419262 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339263 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499264
bncdf80d44fd2016-07-15 20:27:419265 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429266
bncdf80d44fd2016-07-15 20:27:419267 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159268 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429269
bncdf80d44fd2016-07-15 20:27:419270 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429271
9272 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419273 CreateMockRead(stream1_reply, 1, ASYNC),
9274 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359275 CreateMockRead(stream1_body, 4, ASYNC),
9276 CreateMockRead(stream2_body, 5, ASYNC),
9277 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429278 };
9279
9280 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9281 arraysize(spdy_writes));
9282 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9283 // Negotiate SPDY to the proxy
9284 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369285 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429286 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9287
bnc87dcefc2017-05-25 12:47:589288 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199289 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429290 TestCompletionCallback callback;
9291 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429293
9294 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019295 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429296 const HttpResponseInfo* response = trans->GetResponseInfo();
9297
wezca1070932016-05-26 20:30:529298 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429299 EXPECT_TRUE(response->headers->IsKeepAlive());
9300
9301 EXPECT_EQ(200, response->headers->response_code());
9302 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9303
9304 std::string response_data;
9305 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019306 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429307 EXPECT_EQ("hello!", response_data);
9308
9309 trans.reset();
9310 session->CloseAllConnections();
9311}
9312
[email protected]2df19bb2010-08-25 20:13:469313// Test HTTPS connections to a site with a bad certificate, going through an
9314// HTTPS proxy
bncd16676a2016-07-20 16:23:019315TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499316 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9317 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469318
9319 HttpRequestInfo request;
9320 request.method = "GET";
bncce36dca22015-04-21 22:11:239321 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109322 request.traffic_annotation =
9323 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469324
9325 // Attempt to fetch the URL from a server with a bad cert
9326 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179327 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9328 "Host: www.example.org:443\r\n"
9329 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469330 };
9331
9332 MockRead bad_cert_reads[] = {
9333 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069334 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469335 };
9336
9337 // Attempt to fetch the URL with a good cert
9338 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179339 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9340 "Host: www.example.org:443\r\n"
9341 "Proxy-Connection: keep-alive\r\n\r\n"),
9342 MockWrite("GET / HTTP/1.1\r\n"
9343 "Host: www.example.org\r\n"
9344 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469345 };
9346
9347 MockRead good_cert_reads[] = {
9348 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9349 MockRead("HTTP/1.0 200 OK\r\n"),
9350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9351 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069352 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469353 };
9354
9355 StaticSocketDataProvider ssl_bad_certificate(
9356 bad_cert_reads, arraysize(bad_cert_reads),
9357 bad_cert_writes, arraysize(bad_cert_writes));
9358 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9359 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069360 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9361 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469362
9363 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9365 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469367
9368 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9370 session_deps_.socket_factory->AddSocketDataProvider(&data);
9371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469372
[email protected]49639fa2011-12-20 23:22:419373 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469374
danakj1fd259a02016-04-16 03:17:099375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469377
tfarina42834112016-09-22 13:38:209378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469380
9381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019382 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469383
bnc691fda62016-08-12 00:43:169384 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469386
9387 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019388 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469389
bnc691fda62016-08-12 00:43:169390 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469391
wezca1070932016-05-26 20:30:529392 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469393 EXPECT_EQ(100, response->headers->GetContentLength());
9394}
9395
bncd16676a2016-07-20 16:23:019396TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429397 HttpRequestInfo request;
9398 request.method = "GET";
bncce36dca22015-04-21 22:11:239399 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439400 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9401 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109402 request.traffic_annotation =
9403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429404
danakj1fd259a02016-04-16 03:17:099405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279407
[email protected]1c773ea12009-04-28 19:58:429408 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239409 MockWrite(
9410 "GET / HTTP/1.1\r\n"
9411 "Host: www.example.org\r\n"
9412 "Connection: keep-alive\r\n"
9413 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429414 };
9415
9416 // Lastly, the server responds with the actual content.
9417 MockRead data_reads[] = {
9418 MockRead("HTTP/1.0 200 OK\r\n"),
9419 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9420 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069421 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429422 };
9423
[email protected]31a2bfe2010-02-09 08:03:399424 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9425 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079426 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429427
[email protected]49639fa2011-12-20 23:22:419428 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429429
tfarina42834112016-09-22 13:38:209430 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429432
9433 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019434 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429435}
9436
bncd16676a2016-07-20 16:23:019437TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299438 HttpRequestInfo request;
9439 request.method = "GET";
bncce36dca22015-04-21 22:11:239440 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299441 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9442 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109443 request.traffic_annotation =
9444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299445
Ramin Halavatica8d5252018-03-12 05:33:499446 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9447 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279450
[email protected]da81f132010-08-18 23:39:299451 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179452 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9453 "Host: www.example.org:443\r\n"
9454 "Proxy-Connection: keep-alive\r\n"
9455 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299456 };
9457 MockRead data_reads[] = {
9458 // Return an error, so the transaction stops here (this test isn't
9459 // interested in the rest).
9460 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9461 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9462 MockRead("Proxy-Connection: close\r\n\r\n"),
9463 };
9464
9465 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9466 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079467 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299468
[email protected]49639fa2011-12-20 23:22:419469 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299470
tfarina42834112016-09-22 13:38:209471 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299473
9474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019475 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299476}
9477
bncd16676a2016-07-20 16:23:019478TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429479 HttpRequestInfo request;
9480 request.method = "GET";
bncce36dca22015-04-21 22:11:239481 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169482 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9483 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:109484 request.traffic_annotation =
9485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429486
danakj1fd259a02016-04-16 03:17:099487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279489
[email protected]1c773ea12009-04-28 19:58:429490 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239491 MockWrite(
9492 "GET / HTTP/1.1\r\n"
9493 "Host: www.example.org\r\n"
9494 "Connection: keep-alive\r\n"
9495 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429496 };
9497
9498 // Lastly, the server responds with the actual content.
9499 MockRead data_reads[] = {
9500 MockRead("HTTP/1.0 200 OK\r\n"),
9501 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9502 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069503 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429504 };
9505
[email protected]31a2bfe2010-02-09 08:03:399506 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9507 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079508 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429509
[email protected]49639fa2011-12-20 23:22:419510 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429511
tfarina42834112016-09-22 13:38:209512 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429514
9515 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019516 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429517}
9518
bncd16676a2016-07-20 16:23:019519TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429520 HttpRequestInfo request;
9521 request.method = "POST";
bncce36dca22015-04-21 22:11:239522 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109523 request.traffic_annotation =
9524 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429525
danakj1fd259a02016-04-16 03:17:099526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279528
[email protected]1c773ea12009-04-28 19:58:429529 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239530 MockWrite(
9531 "POST / HTTP/1.1\r\n"
9532 "Host: www.example.org\r\n"
9533 "Connection: keep-alive\r\n"
9534 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429535 };
9536
9537 // Lastly, the server responds with the actual content.
9538 MockRead data_reads[] = {
9539 MockRead("HTTP/1.0 200 OK\r\n"),
9540 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9541 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069542 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429543 };
9544
[email protected]31a2bfe2010-02-09 08:03:399545 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9546 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079547 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429548
[email protected]49639fa2011-12-20 23:22:419549 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429550
tfarina42834112016-09-22 13:38:209551 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429553
9554 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019555 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429556}
9557
bncd16676a2016-07-20 16:23:019558TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429559 HttpRequestInfo request;
9560 request.method = "PUT";
bncce36dca22015-04-21 22:11:239561 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109562 request.traffic_annotation =
9563 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429564
danakj1fd259a02016-04-16 03:17:099565 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169566 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279567
[email protected]1c773ea12009-04-28 19:58:429568 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239569 MockWrite(
9570 "PUT / HTTP/1.1\r\n"
9571 "Host: www.example.org\r\n"
9572 "Connection: keep-alive\r\n"
9573 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429574 };
9575
9576 // Lastly, the server responds with the actual content.
9577 MockRead data_reads[] = {
9578 MockRead("HTTP/1.0 200 OK\r\n"),
9579 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9580 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069581 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429582 };
9583
[email protected]31a2bfe2010-02-09 08:03:399584 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9585 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429587
[email protected]49639fa2011-12-20 23:22:419588 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429589
tfarina42834112016-09-22 13:38:209590 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019591 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429592
9593 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019594 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429595}
9596
bncd16676a2016-07-20 16:23:019597TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429598 HttpRequestInfo request;
9599 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239600 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109601 request.traffic_annotation =
9602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429603
danakj1fd259a02016-04-16 03:17:099604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169605 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279606
[email protected]1c773ea12009-04-28 19:58:429607 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139608 MockWrite("HEAD / HTTP/1.1\r\n"
9609 "Host: www.example.org\r\n"
9610 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429611 };
9612
9613 // Lastly, the server responds with the actual content.
9614 MockRead data_reads[] = {
9615 MockRead("HTTP/1.0 200 OK\r\n"),
9616 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9617 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069618 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429619 };
9620
[email protected]31a2bfe2010-02-09 08:03:399621 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9622 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429624
[email protected]49639fa2011-12-20 23:22:419625 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429626
tfarina42834112016-09-22 13:38:209627 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429629
9630 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019631 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429632}
9633
bncd16676a2016-07-20 16:23:019634TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429635 HttpRequestInfo request;
9636 request.method = "GET";
bncce36dca22015-04-21 22:11:239637 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429638 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109639 request.traffic_annotation =
9640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429641
danakj1fd259a02016-04-16 03:17:099642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279644
[email protected]1c773ea12009-04-28 19:58:429645 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239646 MockWrite(
9647 "GET / HTTP/1.1\r\n"
9648 "Host: www.example.org\r\n"
9649 "Connection: keep-alive\r\n"
9650 "Pragma: no-cache\r\n"
9651 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429652 };
9653
9654 // Lastly, the server responds with the actual content.
9655 MockRead data_reads[] = {
9656 MockRead("HTTP/1.0 200 OK\r\n"),
9657 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9658 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069659 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429660 };
9661
[email protected]31a2bfe2010-02-09 08:03:399662 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9663 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079664 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429665
[email protected]49639fa2011-12-20 23:22:419666 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429667
tfarina42834112016-09-22 13:38:209668 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429670
9671 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019672 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429673}
9674
bncd16676a2016-07-20 16:23:019675TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429676 HttpRequestInfo request;
9677 request.method = "GET";
bncce36dca22015-04-21 22:11:239678 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429679 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109680 request.traffic_annotation =
9681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429682
danakj1fd259a02016-04-16 03:17:099683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279685
[email protected]1c773ea12009-04-28 19:58:429686 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239687 MockWrite(
9688 "GET / HTTP/1.1\r\n"
9689 "Host: www.example.org\r\n"
9690 "Connection: keep-alive\r\n"
9691 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429692 };
9693
9694 // Lastly, the server responds with the actual content.
9695 MockRead data_reads[] = {
9696 MockRead("HTTP/1.0 200 OK\r\n"),
9697 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9698 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069699 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429700 };
9701
[email protected]31a2bfe2010-02-09 08:03:399702 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9703 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079704 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429705
[email protected]49639fa2011-12-20 23:22:419706 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429707
tfarina42834112016-09-22 13:38:209708 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429710
9711 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019712 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429713}
9714
bncd16676a2016-07-20 16:23:019715TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429716 HttpRequestInfo request;
9717 request.method = "GET";
bncce36dca22015-04-21 22:11:239718 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439719 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:109720 request.traffic_annotation =
9721 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429722
danakj1fd259a02016-04-16 03:17:099723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279725
[email protected]1c773ea12009-04-28 19:58:429726 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239727 MockWrite(
9728 "GET / HTTP/1.1\r\n"
9729 "Host: www.example.org\r\n"
9730 "Connection: keep-alive\r\n"
9731 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429732 };
9733
9734 // Lastly, the server responds with the actual content.
9735 MockRead data_reads[] = {
9736 MockRead("HTTP/1.0 200 OK\r\n"),
9737 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9738 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069739 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429740 };
9741
[email protected]31a2bfe2010-02-09 08:03:399742 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9743 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079744 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429745
[email protected]49639fa2011-12-20 23:22:419746 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429747
tfarina42834112016-09-22 13:38:209748 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429750
9751 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019752 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429753}
9754
bncd16676a2016-07-20 16:23:019755TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479756 HttpRequestInfo request;
9757 request.method = "GET";
bncce36dca22015-04-21 22:11:239758 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439759 request.extra_headers.SetHeader("referer", "www.foo.com");
9760 request.extra_headers.SetHeader("hEllo", "Kitty");
9761 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:109762 request.traffic_annotation =
9763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479764
danakj1fd259a02016-04-16 03:17:099765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279767
[email protected]270c6412010-03-29 22:02:479768 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239769 MockWrite(
9770 "GET / HTTP/1.1\r\n"
9771 "Host: www.example.org\r\n"
9772 "Connection: keep-alive\r\n"
9773 "referer: www.foo.com\r\n"
9774 "hEllo: Kitty\r\n"
9775 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479776 };
9777
9778 // Lastly, the server responds with the actual content.
9779 MockRead data_reads[] = {
9780 MockRead("HTTP/1.0 200 OK\r\n"),
9781 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9782 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069783 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479784 };
9785
9786 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9787 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079788 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479789
[email protected]49639fa2011-12-20 23:22:419790 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479791
tfarina42834112016-09-22 13:38:209792 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479794
9795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019796 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479797}
9798
bncd16676a2016-07-20 16:23:019799TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279800 HttpRequestInfo request;
9801 request.method = "GET";
bncce36dca22015-04-21 22:11:239802 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109803 request.traffic_annotation =
9804 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279805
Lily Houghton8c2f97d2018-01-22 05:06:599806 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499807 ProxyResolutionService::CreateFixedFromPacResult(
9808 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519809 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079810 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029811
danakj1fd259a02016-04-16 03:17:099812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029814
[email protected]3cd17242009-06-23 02:59:029815 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9816 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9817
9818 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239819 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9820 MockWrite(
9821 "GET / HTTP/1.1\r\n"
9822 "Host: www.example.org\r\n"
9823 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029824
9825 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069826 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029827 MockRead("HTTP/1.0 200 OK\r\n"),
9828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9829 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069830 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029831 };
9832
[email protected]31a2bfe2010-02-09 08:03:399833 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9834 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079835 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029836
[email protected]49639fa2011-12-20 23:22:419837 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029838
tfarina42834112016-09-22 13:38:209839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029841
9842 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019843 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029844
bnc691fda62016-08-12 00:43:169845 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529846 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029847
tbansal2ecbbc72016-10-06 17:15:479848 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209849 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169850 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209851 TestLoadTimingNotReusedWithPac(load_timing_info,
9852 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9853
[email protected]3cd17242009-06-23 02:59:029854 std::string response_text;
bnc691fda62016-08-12 00:43:169855 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019856 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029857 EXPECT_EQ("Payload", response_text);
9858}
9859
bncd16676a2016-07-20 16:23:019860TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279861 HttpRequestInfo request;
9862 request.method = "GET";
bncce36dca22015-04-21 22:11:239863 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109864 request.traffic_annotation =
9865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279866
Lily Houghton8c2f97d2018-01-22 05:06:599867 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499868 ProxyResolutionService::CreateFixedFromPacResult(
9869 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519870 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079871 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029872
danakj1fd259a02016-04-16 03:17:099873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029875
[email protected]3cd17242009-06-23 02:59:029876 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9877 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9878
9879 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239880 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9881 arraysize(write_buffer)),
9882 MockWrite(
9883 "GET / HTTP/1.1\r\n"
9884 "Host: www.example.org\r\n"
9885 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029886
9887 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019888 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9889 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359890 MockRead("HTTP/1.0 200 OK\r\n"),
9891 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9892 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069893 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359894 };
9895
[email protected]31a2bfe2010-02-09 08:03:399896 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9897 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079898 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359899
[email protected]8ddf8322012-02-23 18:08:069900 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359902
[email protected]49639fa2011-12-20 23:22:419903 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359904
tfarina42834112016-09-22 13:38:209905 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359907
9908 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019909 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359910
[email protected]029c83b62013-01-24 05:28:209911 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169912 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209913 TestLoadTimingNotReusedWithPac(load_timing_info,
9914 CONNECT_TIMING_HAS_SSL_TIMES);
9915
bnc691fda62016-08-12 00:43:169916 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529917 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479918 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359919
9920 std::string response_text;
bnc691fda62016-08-12 00:43:169921 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019922 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359923 EXPECT_EQ("Payload", response_text);
9924}
9925
bncd16676a2016-07-20 16:23:019926TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209927 HttpRequestInfo request;
9928 request.method = "GET";
bncce36dca22015-04-21 22:11:239929 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109930 request.traffic_annotation =
9931 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209932
Ramin Halavatica8d5252018-03-12 05:33:499933 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9934 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519935 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079936 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209937
danakj1fd259a02016-04-16 03:17:099938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209940
9941 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9942 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9943
9944 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239945 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9946 MockWrite(
9947 "GET / HTTP/1.1\r\n"
9948 "Host: www.example.org\r\n"
9949 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209950
9951 MockRead data_reads[] = {
9952 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9953 MockRead("HTTP/1.0 200 OK\r\n"),
9954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9955 MockRead("Payload"),
9956 MockRead(SYNCHRONOUS, OK)
9957 };
9958
9959 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9960 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079961 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209962
9963 TestCompletionCallback callback;
9964
tfarina42834112016-09-22 13:38:209965 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209967
9968 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019969 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209970
bnc691fda62016-08-12 00:43:169971 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529972 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209973
9974 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169975 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209976 TestLoadTimingNotReused(load_timing_info,
9977 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9978
9979 std::string response_text;
bnc691fda62016-08-12 00:43:169980 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019981 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209982 EXPECT_EQ("Payload", response_text);
9983}
9984
bncd16676a2016-07-20 16:23:019985TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279986 HttpRequestInfo request;
9987 request.method = "GET";
bncce36dca22015-04-21 22:11:239988 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109989 request.traffic_annotation =
9990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279991
Lily Houghton8c2f97d2018-01-22 05:06:599992 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499993 ProxyResolutionService::CreateFixedFromPacResult(
9994 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519995 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079996 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359997
danakj1fd259a02016-04-16 03:17:099998 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510000
[email protected]e0c27be2009-07-15 13:09:3510001 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10002 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710003 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310004 0x05, // Version
10005 0x01, // Command (CONNECT)
10006 0x00, // Reserved.
10007 0x03, // Address type (DOMAINNAME).
10008 0x0F, // Length of domain (15)
10009 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10010 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710011 };
[email protected]e0c27be2009-07-15 13:09:3510012 const char kSOCKS5OkResponse[] =
10013 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10014
10015 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310016 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10017 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10018 MockWrite(
10019 "GET / HTTP/1.1\r\n"
10020 "Host: www.example.org\r\n"
10021 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510022
10023 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110024 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10025 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510026 MockRead("HTTP/1.0 200 OK\r\n"),
10027 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10028 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610029 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510030 };
10031
[email protected]31a2bfe2010-02-09 08:03:3910032 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10033 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710034 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510035
[email protected]49639fa2011-12-20 23:22:4110036 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510037
tfarina42834112016-09-22 13:38:2010038 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510040
10041 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110042 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510043
bnc691fda62016-08-12 00:43:1610044 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210045 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710046 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510047
[email protected]029c83b62013-01-24 05:28:2010048 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610049 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010050 TestLoadTimingNotReusedWithPac(load_timing_info,
10051 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10052
[email protected]e0c27be2009-07-15 13:09:3510053 std::string response_text;
bnc691fda62016-08-12 00:43:1610054 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110055 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510056 EXPECT_EQ("Payload", response_text);
10057}
10058
bncd16676a2016-07-20 16:23:0110059TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710060 HttpRequestInfo request;
10061 request.method = "GET";
bncce36dca22015-04-21 22:11:2310062 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010063 request.traffic_annotation =
10064 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710065
Lily Houghton8c2f97d2018-01-22 05:06:5910066 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910067 ProxyResolutionService::CreateFixedFromPacResult(
10068 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110069 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710070 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510071
danakj1fd259a02016-04-16 03:17:0910072 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510074
[email protected]e0c27be2009-07-15 13:09:3510075 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10076 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710077 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310078 0x05, // Version
10079 0x01, // Command (CONNECT)
10080 0x00, // Reserved.
10081 0x03, // Address type (DOMAINNAME).
10082 0x0F, // Length of domain (15)
10083 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10084 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710085 };
10086
[email protected]e0c27be2009-07-15 13:09:3510087 const char kSOCKS5OkResponse[] =
10088 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10089
10090 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310091 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10092 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10093 arraysize(kSOCKS5OkRequest)),
10094 MockWrite(
10095 "GET / HTTP/1.1\r\n"
10096 "Host: www.example.org\r\n"
10097 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510098
10099 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110100 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10101 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210102 MockRead("HTTP/1.0 200 OK\r\n"),
10103 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10104 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610105 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210106 };
10107
[email protected]31a2bfe2010-02-09 08:03:3910108 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10109 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710110 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210111
[email protected]8ddf8322012-02-23 18:08:0610112 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210114
[email protected]49639fa2011-12-20 23:22:4110115 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210116
tfarina42834112016-09-22 13:38:2010117 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210119
10120 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110121 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210122
bnc691fda62016-08-12 00:43:1610123 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210124 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710125 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210126
[email protected]029c83b62013-01-24 05:28:2010127 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610128 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010129 TestLoadTimingNotReusedWithPac(load_timing_info,
10130 CONNECT_TIMING_HAS_SSL_TIMES);
10131
[email protected]3cd17242009-06-23 02:59:0210132 std::string response_text;
bnc691fda62016-08-12 00:43:1610133 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110134 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210135 EXPECT_EQ("Payload", response_text);
10136}
10137
[email protected]448d4ca52012-03-04 04:12:2310138namespace {
10139
[email protected]04e5be32009-06-26 20:00:3110140// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610141
10142struct GroupNameTest {
10143 std::string proxy_server;
10144 std::string url;
10145 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810146 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610147};
10148
danakj1fd259a02016-04-16 03:17:0910149std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710150 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910151 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610152
bnc525e175a2016-06-20 12:36:4010153 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310154 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110155 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210156 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110157 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210158 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610159 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610160
10161 return session;
10162}
10163
mmenkee65e7af2015-10-13 17:16:4210164int GroupNameTransactionHelper(const std::string& url,
10165 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610166 HttpRequestInfo request;
10167 request.method = "GET";
10168 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1010169 request.traffic_annotation =
10170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610171
bnc691fda62016-08-12 00:43:1610172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710173
[email protected]49639fa2011-12-20 23:22:4110174 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610175
10176 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010177 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610178}
10179
[email protected]448d4ca52012-03-04 04:12:2310180} // namespace
10181
bncd16676a2016-07-20 16:23:0110182TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610183 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310184 {
10185 "", // unused
10186 "http://www.example.org/direct",
10187 "www.example.org:80",
10188 false,
10189 },
10190 {
10191 "", // unused
10192 "http://[2001:1418:13:1::25]/direct",
10193 "[2001:1418:13:1::25]:80",
10194 false,
10195 },
[email protected]04e5be32009-06-26 20:00:3110196
bncce36dca22015-04-21 22:11:2310197 // SSL Tests
10198 {
10199 "", // unused
10200 "https://www.example.org/direct_ssl",
10201 "ssl/www.example.org:443",
10202 true,
10203 },
10204 {
10205 "", // unused
10206 "https://[2001:1418:13:1::25]/direct",
10207 "ssl/[2001:1418:13:1::25]:443",
10208 true,
10209 },
10210 {
10211 "", // unused
bncaa60ff402016-06-22 19:12:4210212 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310213 "ssl/host.with.alternate:443",
10214 true,
10215 },
[email protected]2d731a32010-04-29 01:04:0610216 };
[email protected]2ff8b312010-04-26 22:20:5410217
viettrungluue4a8b882014-10-16 06:17:3810218 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910219 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910220 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10221 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910222 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010223 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610224
mmenkee65e7af2015-10-13 17:16:4210225 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810226 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810227 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310228 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810229 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910230 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210231 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10232 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810233 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610234
10235 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210236 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910237 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810238 EXPECT_EQ(tests[i].expected_group_name,
10239 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910240 } else {
[email protected]e60e47a2010-07-14 03:37:1810241 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810242 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910243 }
10244 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10245 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10246 // When SSL proxy is not in use, socket must be requested from
10247 // |transport_conn_pool|.
10248 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610249 }
[email protected]2d731a32010-04-29 01:04:0610250}
10251
bncd16676a2016-07-20 16:23:0110252TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610253 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310254 {
Matt Menked1eb6d42018-01-17 04:54:0610255 "http_proxy", "http://www.example.org/http_proxy_normal",
10256 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310257 },
[email protected]2d731a32010-04-29 01:04:0610258
bncce36dca22015-04-21 22:11:2310259 // SSL Tests
10260 {
Matt Menked1eb6d42018-01-17 04:54:0610261 "http_proxy", "https://www.example.org/http_connect_ssl",
10262 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310263 },
[email protected]af3490e2010-10-16 21:02:2910264
bncce36dca22015-04-21 22:11:2310265 {
Matt Menked1eb6d42018-01-17 04:54:0610266 "http_proxy", "https://host.with.alternate/direct",
10267 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310268 },
[email protected]45499252013-01-23 17:12:5610269
bncce36dca22015-04-21 22:11:2310270 {
Matt Menked1eb6d42018-01-17 04:54:0610271 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10272 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310273 },
[email protected]2d731a32010-04-29 01:04:0610274 };
10275
viettrungluue4a8b882014-10-16 06:17:3810276 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910277 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910278 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10279 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910280 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010281 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610282
mmenkee65e7af2015-10-13 17:16:4210283 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610284
[email protected]e60e47a2010-07-14 03:37:1810285 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310286 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410287 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310288 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410289 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910290 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910291 mock_pool_manager->SetSocketPoolForHTTPProxy(
10292 proxy_host, base::WrapUnique(http_proxy_pool));
10293 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10294 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810295 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610296
10297 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210298 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810299 if (tests[i].ssl)
10300 EXPECT_EQ(tests[i].expected_group_name,
10301 ssl_conn_pool->last_group_name_received());
10302 else
10303 EXPECT_EQ(tests[i].expected_group_name,
10304 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610305 }
[email protected]2d731a32010-04-29 01:04:0610306}
10307
bncd16676a2016-07-20 16:23:0110308TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610309 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310310 {
10311 "socks4://socks_proxy:1080",
10312 "http://www.example.org/socks4_direct",
10313 "socks4/www.example.org:80",
10314 false,
10315 },
10316 {
10317 "socks5://socks_proxy:1080",
10318 "http://www.example.org/socks5_direct",
10319 "socks5/www.example.org:80",
10320 false,
10321 },
[email protected]2d731a32010-04-29 01:04:0610322
bncce36dca22015-04-21 22:11:2310323 // SSL Tests
10324 {
10325 "socks4://socks_proxy:1080",
10326 "https://www.example.org/socks4_ssl",
10327 "socks4/ssl/www.example.org:443",
10328 true,
10329 },
10330 {
10331 "socks5://socks_proxy:1080",
10332 "https://www.example.org/socks5_ssl",
10333 "socks5/ssl/www.example.org:443",
10334 true,
10335 },
[email protected]af3490e2010-10-16 21:02:2910336
bncce36dca22015-04-21 22:11:2310337 {
10338 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210339 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310340 "socks4/ssl/host.with.alternate:443",
10341 true,
10342 },
[email protected]04e5be32009-06-26 20:00:3110343 };
10344
viettrungluue4a8b882014-10-16 06:17:3810345 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910346 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910347 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10348 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910349 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010350 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210351
mmenkee65e7af2015-10-13 17:16:4210352 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110353
[email protected]e60e47a2010-07-14 03:37:1810354 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310355 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410356 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310357 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410358 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910359 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910360 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10361 proxy_host, base::WrapUnique(socks_conn_pool));
10362 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10363 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810364 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110365
bnc691fda62016-08-12 00:43:1610366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110367
[email protected]2d731a32010-04-29 01:04:0610368 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210369 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810370 if (tests[i].ssl)
10371 EXPECT_EQ(tests[i].expected_group_name,
10372 ssl_conn_pool->last_group_name_received());
10373 else
10374 EXPECT_EQ(tests[i].expected_group_name,
10375 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110376 }
10377}
10378
bncd16676a2016-07-20 16:23:0110379TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710380 HttpRequestInfo request;
10381 request.method = "GET";
bncce36dca22015-04-21 22:11:2310382 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010383 request.traffic_annotation =
10384 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710385
Ramin Halavatica8d5252018-03-12 05:33:4910386 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10387 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210388
[email protected]69719062010-01-05 20:09:2110389 // This simulates failure resolving all hostnames; that means we will fail
10390 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710391 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210392
danakj1fd259a02016-04-16 03:17:0910393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510395
[email protected]49639fa2011-12-20 23:22:4110396 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510397
tfarina42834112016-09-22 13:38:2010398 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510400
[email protected]9172a982009-06-06 00:30:2510401 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110402 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510403}
10404
[email protected]685af592010-05-11 19:31:2410405// Base test to make sure that when the load flags for a request specify to
10406// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210407void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710408 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710409 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010410 HttpRequestInfo request_info;
10411 request_info.method = "GET";
10412 request_info.load_flags = load_flags;
10413 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010414 request_info.traffic_annotation =
10415 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710416
[email protected]a2c2fb92009-07-18 07:31:0410417 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910418 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210419
danakj1fd259a02016-04-16 03:17:0910420 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610421 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810422
bncce36dca22015-04-21 22:11:2310423 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810424 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910425 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010426 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710427 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310428 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010429 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010430 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710432 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110433 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810434
10435 // Verify that it was added to host cache, by doing a subsequent async lookup
10436 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010437 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710438 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310439 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010440 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010441 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110442 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810443
bncce36dca22015-04-21 22:11:2310444 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810445 // we can tell if the next lookup hit the cache, or the "network".
10446 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310447 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810448
10449 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10450 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610451 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910452 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710453 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810454
[email protected]3b9cca42009-06-16 01:08:2810455 // Run the request.
tfarina42834112016-09-22 13:38:2010456 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110457 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110458 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810459
10460 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310461 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110462 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810463}
10464
[email protected]685af592010-05-11 19:31:2410465// There are multiple load flags that should trigger the host cache bypass.
10466// Test each in isolation:
bncd16676a2016-07-20 16:23:0110467TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410468 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10469}
10470
bncd16676a2016-07-20 16:23:0110471TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410472 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10473}
10474
bncd16676a2016-07-20 16:23:0110475TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410476 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10477}
10478
[email protected]0877e3d2009-10-17 22:29:5710479// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110480TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710481 HttpRequestInfo request;
10482 request.method = "GET";
10483 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010484 request.traffic_annotation =
10485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710486
10487 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610488 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710489 };
[email protected]31a2bfe2010-02-09 08:03:3910490 StaticSocketDataProvider data(NULL, 0,
10491 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710492 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710494
[email protected]49639fa2011-12-20 23:22:4110495 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710496
bnc691fda62016-08-12 00:43:1610497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710498
tfarina42834112016-09-22 13:38:2010499 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710501
10502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110503 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910504
10505 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610506 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910507 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710508}
10509
zmo9528c9f42015-08-04 22:12:0810510// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110511TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710512 HttpRequestInfo request;
10513 request.method = "GET";
10514 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010515 request.traffic_annotation =
10516 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710517
10518 MockRead data_reads[] = {
10519 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610520 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710521 };
10522
[email protected]31a2bfe2010-02-09 08:03:3910523 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710524 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910525 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710526
[email protected]49639fa2011-12-20 23:22:4110527 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710528
bnc691fda62016-08-12 00:43:1610529 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710530
tfarina42834112016-09-22 13:38:2010531 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710533
10534 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110535 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810536
bnc691fda62016-08-12 00:43:1610537 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210538 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810539
wezca1070932016-05-26 20:30:5210540 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810541 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10542
10543 std::string response_data;
bnc691fda62016-08-12 00:43:1610544 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110545 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810546 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910547
10548 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610549 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910550 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710551}
10552
10553// Make sure that a dropped connection while draining the body for auth
10554// restart does the right thing.
bncd16676a2016-07-20 16:23:0110555TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710556 HttpRequestInfo request;
10557 request.method = "GET";
bncce36dca22015-04-21 22:11:2310558 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010559 request.traffic_annotation =
10560 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710561
10562 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310563 MockWrite(
10564 "GET / HTTP/1.1\r\n"
10565 "Host: www.example.org\r\n"
10566 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710567 };
10568
10569 MockRead data_reads1[] = {
10570 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10571 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10572 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10573 MockRead("Content-Length: 14\r\n\r\n"),
10574 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610575 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710576 };
10577
[email protected]31a2bfe2010-02-09 08:03:3910578 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10579 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710580 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710581
bnc691fda62016-08-12 00:43:1610582 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710583 // be issuing -- the final header line contains the credentials.
10584 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310585 MockWrite(
10586 "GET / HTTP/1.1\r\n"
10587 "Host: www.example.org\r\n"
10588 "Connection: keep-alive\r\n"
10589 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710590 };
10591
10592 // Lastly, the server responds with the actual content.
10593 MockRead data_reads2[] = {
10594 MockRead("HTTP/1.1 200 OK\r\n"),
10595 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10596 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610597 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710598 };
10599
[email protected]31a2bfe2010-02-09 08:03:3910600 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10601 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710602 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710604
[email protected]49639fa2011-12-20 23:22:4110605 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710606
bnc691fda62016-08-12 00:43:1610607 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010608
tfarina42834112016-09-22 13:38:2010609 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710611
10612 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110613 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710614
bnc691fda62016-08-12 00:43:1610615 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210616 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410617 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710618
[email protected]49639fa2011-12-20 23:22:4110619 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710620
bnc691fda62016-08-12 00:43:1610621 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110622 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710623
10624 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110625 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710626
bnc691fda62016-08-12 00:43:1610627 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210628 ASSERT_TRUE(response);
10629 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710630 EXPECT_EQ(100, response->headers->GetContentLength());
10631}
10632
10633// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110634TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910635 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10636 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710637
10638 HttpRequestInfo request;
10639 request.method = "GET";
bncce36dca22015-04-21 22:11:2310640 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010641 request.traffic_annotation =
10642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710643
10644 MockRead proxy_reads[] = {
10645 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610646 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710647 };
10648
[email protected]31a2bfe2010-02-09 08:03:3910649 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610650 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710651
[email protected]bb88e1d32013-05-03 23:11:0710652 session_deps_.socket_factory->AddSocketDataProvider(&data);
10653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710654
[email protected]49639fa2011-12-20 23:22:4110655 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710656
[email protected]bb88e1d32013-05-03 23:11:0710657 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710658
danakj1fd259a02016-04-16 03:17:0910659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710661
tfarina42834112016-09-22 13:38:2010662 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110663 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710664
10665 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110666 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710667}
10668
bncd16676a2016-07-20 16:23:0110669TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610670 HttpRequestInfo request;
10671 request.method = "GET";
bncce36dca22015-04-21 22:11:2310672 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010673 request.traffic_annotation =
10674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610675
danakj1fd259a02016-04-16 03:17:0910676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710678
[email protected]e22e1362009-11-23 21:31:1210679 MockRead data_reads[] = {
10680 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610681 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210682 };
[email protected]9492e4a2010-02-24 00:58:4610683
10684 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710685 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610686
[email protected]49639fa2011-12-20 23:22:4110687 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610688
tfarina42834112016-09-22 13:38:2010689 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610691
robpercival214763f2016-07-01 23:27:0110692 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610693
bnc691fda62016-08-12 00:43:1610694 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210695 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610696
wezca1070932016-05-26 20:30:5210697 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610698 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10699
10700 std::string response_data;
bnc691fda62016-08-12 00:43:1610701 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110702 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210703}
10704
bncd16676a2016-07-20 16:23:0110705TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510706 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210707 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410708 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110709 UploadFileElementReader::ScopedOverridingContentLengthForTests
10710 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310711
danakj1fd259a02016-04-16 03:17:0910712 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910713 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410714 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710715 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210716 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710717
10718 HttpRequestInfo request;
10719 request.method = "POST";
bncce36dca22015-04-21 22:11:2310720 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710721 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010722 request.traffic_annotation =
10723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710724
danakj1fd259a02016-04-16 03:17:0910725 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310727
10728 MockRead data_reads[] = {
10729 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10730 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610731 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310732 };
[email protected]31a2bfe2010-02-09 08:03:3910733 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710734 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310735
[email protected]49639fa2011-12-20 23:22:4110736 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310737
tfarina42834112016-09-22 13:38:2010738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310740
10741 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110742 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310743
bnc691fda62016-08-12 00:43:1610744 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210745 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310746
maksim.sisove869bf52016-06-23 17:11:5210747 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310748
[email protected]dd3aa792013-07-16 19:10:2310749 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310750}
10751
bncd16676a2016-07-20 16:23:0110752TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510753 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210754 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610755 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810756 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10757 base::WriteFile(temp_file, temp_file_content.c_str(),
10758 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110759 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610760
danakj1fd259a02016-04-16 03:17:0910761 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910762 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410763 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710764 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210765 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710766
10767 HttpRequestInfo request;
10768 request.method = "POST";
bncce36dca22015-04-21 22:11:2310769 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710770 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010771 request.traffic_annotation =
10772 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710773
[email protected]999dd8c2013-11-12 06:45:5410774 // If we try to upload an unreadable file, the transaction should fail.
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]6624b4622010-03-29 19:58:3610777
[email protected]999dd8c2013-11-12 06:45:5410778 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710779 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610780
[email protected]49639fa2011-12-20 23:22:4110781 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610782
tfarina42834112016-09-22 13:38:2010783 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610785
10786 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110787 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610788
[email protected]dd3aa792013-07-16 19:10:2310789 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610790}
10791
bncd16676a2016-07-20 16:23:0110792TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310793 class FakeUploadElementReader : public UploadElementReader {
10794 public:
Chris Watkins7a41d3552017-12-01 02:13:2710795 FakeUploadElementReader() = default;
10796 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310797
Matt Menkecc1d3a902018-02-05 18:27:3310798 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310799
10800 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310801 int Init(CompletionOnceCallback callback) override {
10802 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310803 return ERR_IO_PENDING;
10804 }
avibf0746c2015-12-09 19:53:1410805 uint64_t GetContentLength() const override { return 0; }
10806 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010807 int Read(IOBuffer* buf,
10808 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310809 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310810 return ERR_FAILED;
10811 }
10812
10813 private:
Matt Menkecc1d3a902018-02-05 18:27:3310814 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310815 };
10816
10817 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910818 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10819 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210820 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310821
10822 HttpRequestInfo request;
10823 request.method = "POST";
bncce36dca22015-04-21 22:11:2310824 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310825 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010826 request.traffic_annotation =
10827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310828
danakj1fd259a02016-04-16 03:17:0910829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810830 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910831 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310832
10833 StaticSocketDataProvider data;
10834 session_deps_.socket_factory->AddSocketDataProvider(&data);
10835
10836 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010837 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510839 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310840
10841 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310842 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10843 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310844
10845 // Return Init()'s result after the transaction gets destroyed.
10846 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310847 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310848}
10849
[email protected]aeefc9e82010-02-19 16:18:2710850// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110851TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710852 HttpRequestInfo request;
10853 request.method = "GET";
bncce36dca22015-04-21 22:11:2310854 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010855 request.traffic_annotation =
10856 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710857
10858 // First transaction will request a resource and receive a Basic challenge
10859 // with realm="first_realm".
10860 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310861 MockWrite(
10862 "GET / HTTP/1.1\r\n"
10863 "Host: www.example.org\r\n"
10864 "Connection: keep-alive\r\n"
10865 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710866 };
10867 MockRead data_reads1[] = {
10868 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10869 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10870 "\r\n"),
10871 };
10872
bnc691fda62016-08-12 00:43:1610873 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710874 // for first_realm. The server will reject and provide a challenge with
10875 // second_realm.
10876 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310877 MockWrite(
10878 "GET / HTTP/1.1\r\n"
10879 "Host: www.example.org\r\n"
10880 "Connection: keep-alive\r\n"
10881 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10882 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710883 };
10884 MockRead data_reads2[] = {
10885 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10886 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10887 "\r\n"),
10888 };
10889
10890 // This again fails, and goes back to first_realm. Make sure that the
10891 // entry is removed from cache.
10892 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310893 MockWrite(
10894 "GET / HTTP/1.1\r\n"
10895 "Host: www.example.org\r\n"
10896 "Connection: keep-alive\r\n"
10897 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10898 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710899 };
10900 MockRead data_reads3[] = {
10901 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10902 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10903 "\r\n"),
10904 };
10905
10906 // Try one last time (with the correct password) and get the resource.
10907 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310908 MockWrite(
10909 "GET / HTTP/1.1\r\n"
10910 "Host: www.example.org\r\n"
10911 "Connection: keep-alive\r\n"
10912 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10913 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710914 };
10915 MockRead data_reads4[] = {
10916 MockRead("HTTP/1.1 200 OK\r\n"
10917 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010918 "Content-Length: 5\r\n"
10919 "\r\n"
10920 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710921 };
10922
10923 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10924 data_writes1, arraysize(data_writes1));
10925 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10926 data_writes2, arraysize(data_writes2));
10927 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10928 data_writes3, arraysize(data_writes3));
10929 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10930 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10932 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10933 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10934 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710935
[email protected]49639fa2011-12-20 23:22:4110936 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710937
danakj1fd259a02016-04-16 03:17:0910938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010940
[email protected]aeefc9e82010-02-19 16:18:2710941 // Issue the first request with Authorize headers. There should be a
10942 // password prompt for first_realm waiting to be filled in after the
10943 // transaction completes.
tfarina42834112016-09-22 13:38:2010944 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710946 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110947 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610948 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210949 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410950 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210951 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410952 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310953 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410954 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910955 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710956
10957 // Issue the second request with an incorrect password. There should be a
10958 // password prompt for second_realm waiting to be filled in after the
10959 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110960 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610961 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10962 callback2.callback());
robpercival214763f2016-07-01 23:27:0110963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710964 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110965 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610966 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210967 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410968 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210969 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410970 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310971 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410972 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910973 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710974
10975 // Issue the third request with another incorrect password. There should be
10976 // a password prompt for first_realm waiting to be filled in. If the password
10977 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10978 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110979 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610980 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10981 callback3.callback());
robpercival214763f2016-07-01 23:27:0110982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710983 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110984 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610985 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210986 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410987 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210988 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410989 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310990 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410991 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910992 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710993
10994 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110995 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610996 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10997 callback4.callback());
robpercival214763f2016-07-01 23:27:0110998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710999 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111000 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611001 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211002 ASSERT_TRUE(response);
11003 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711004}
11005
Bence Béky230ac612017-08-30 19:17:0811006// Regression test for https://crbug.com/754395.
11007TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11008 MockRead data_reads[] = {
11009 MockRead("HTTP/1.1 200 OK\r\n"),
11010 MockRead(kAlternativeServiceHttpHeader),
11011 MockRead("\r\n"),
11012 MockRead("hello world"),
11013 MockRead(SYNCHRONOUS, OK),
11014 };
11015
11016 HttpRequestInfo request;
11017 request.method = "GET";
11018 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011019 request.traffic_annotation =
11020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811021
11022 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11023 session_deps_.socket_factory->AddSocketDataProvider(&data);
11024
11025 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911026 ssl.ssl_info.cert =
11027 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11028 ASSERT_TRUE(ssl.ssl_info.cert);
11029 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11031
11032 TestCompletionCallback callback;
11033
11034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11036
11037 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11039
11040 url::SchemeHostPort test_server(request.url);
11041 HttpServerProperties* http_server_properties =
11042 session->http_server_properties();
11043 EXPECT_TRUE(
11044 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11045
11046 EXPECT_THAT(callback.WaitForResult(), IsOk());
11047
11048 const HttpResponseInfo* response = trans.GetResponseInfo();
11049 ASSERT_TRUE(response);
11050 ASSERT_TRUE(response->headers);
11051 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11052 EXPECT_FALSE(response->was_fetched_via_spdy);
11053 EXPECT_FALSE(response->was_alpn_negotiated);
11054
11055 std::string response_data;
11056 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11057 EXPECT_EQ("hello world", response_data);
11058
11059 EXPECT_TRUE(
11060 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11061}
11062
bncd16676a2016-07-20 16:23:0111063TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211064 MockRead data_reads[] = {
11065 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311066 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211067 MockRead("\r\n"),
11068 MockRead("hello world"),
11069 MockRead(SYNCHRONOUS, OK),
11070 };
11071
11072 HttpRequestInfo request;
11073 request.method = "GET";
bncb26024382016-06-29 02:39:4511074 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011075 request.traffic_annotation =
11076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211077
11078 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211079 session_deps_.socket_factory->AddSocketDataProvider(&data);
11080
bncb26024382016-06-29 02:39:4511081 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911082 ssl.ssl_info.cert =
11083 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11084 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11086
bncc958faa2015-07-31 18:14:5211087 TestCompletionCallback callback;
11088
danakj1fd259a02016-04-16 03:17:0911089 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611090 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211091
tfarina42834112016-09-22 13:38:2011092 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211094
bncb26024382016-06-29 02:39:4511095 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011096 HttpServerProperties* http_server_properties =
11097 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411098 EXPECT_TRUE(
11099 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211100
robpercival214763f2016-07-01 23:27:0111101 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211102
bnc691fda62016-08-12 00:43:1611103 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211104 ASSERT_TRUE(response);
11105 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211106 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11107 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211108 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211109
11110 std::string response_data;
bnc691fda62016-08-12 00:43:1611111 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211112 EXPECT_EQ("hello world", response_data);
11113
zhongyic4de03032017-05-19 04:07:3411114 AlternativeServiceInfoVector alternative_service_info_vector =
11115 http_server_properties->GetAlternativeServiceInfos(test_server);
11116 ASSERT_EQ(1u, alternative_service_info_vector.size());
11117 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11118 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411119 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211120}
11121
bnce3dd56f2016-06-01 10:37:1111122// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111123TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111124 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111125 MockRead data_reads[] = {
11126 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311127 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111128 MockRead("\r\n"),
11129 MockRead("hello world"),
11130 MockRead(SYNCHRONOUS, OK),
11131 };
11132
11133 HttpRequestInfo request;
11134 request.method = "GET";
11135 request.url = GURL("http://www.example.org/");
11136 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011137 request.traffic_annotation =
11138 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111139
11140 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11141 session_deps_.socket_factory->AddSocketDataProvider(&data);
11142
11143 TestCompletionCallback callback;
11144
11145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611146 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111147
11148 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011149 HttpServerProperties* http_server_properties =
11150 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411151 EXPECT_TRUE(
11152 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111153
tfarina42834112016-09-22 13:38:2011154 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11156 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111157
bnc691fda62016-08-12 00:43:1611158 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111159 ASSERT_TRUE(response);
11160 ASSERT_TRUE(response->headers);
11161 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11162 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211163 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111164
11165 std::string response_data;
bnc691fda62016-08-12 00:43:1611166 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111167 EXPECT_EQ("hello world", response_data);
11168
zhongyic4de03032017-05-19 04:07:3411169 EXPECT_TRUE(
11170 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111171}
11172
bnca86731e2017-04-17 12:31:2811173// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511174// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111175TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511176 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811177 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511178
bnc8bef8da22016-05-30 01:28:2511179 HttpRequestInfo request;
11180 request.method = "GET";
bncb26024382016-06-29 02:39:4511181 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511182 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011183 request.traffic_annotation =
11184 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511185
11186 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11187 StaticSocketDataProvider first_data;
11188 first_data.set_connect_data(mock_connect);
11189 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511190 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611191 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511192 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511193
11194 MockRead data_reads[] = {
11195 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11196 MockRead(ASYNC, OK),
11197 };
11198 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11199 0);
11200 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11201
11202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11203
bnc525e175a2016-06-20 12:36:4011204 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511205 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111206 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11207 444);
bnc8bef8da22016-05-30 01:28:2511208 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111209 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511210 url::SchemeHostPort(request.url), alternative_service, expiration);
11211
bnc691fda62016-08-12 00:43:1611212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511213 TestCompletionCallback callback;
11214
tfarina42834112016-09-22 13:38:2011215 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511216 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111217 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511218}
11219
bnce3dd56f2016-06-01 10:37:1111220// Regression test for https://crbug.com/615497:
11221// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111222TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111223 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111224 HttpRequestInfo request;
11225 request.method = "GET";
11226 request.url = GURL("http://www.example.org/");
11227 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011228 request.traffic_annotation =
11229 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111230
11231 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11232 StaticSocketDataProvider first_data;
11233 first_data.set_connect_data(mock_connect);
11234 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11235
11236 MockRead data_reads[] = {
11237 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11238 MockRead(ASYNC, OK),
11239 };
11240 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11241 0);
11242 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11243
11244 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11245
bnc525e175a2016-06-20 12:36:4011246 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111247 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111248 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111249 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111250 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111251 url::SchemeHostPort(request.url), alternative_service, expiration);
11252
bnc691fda62016-08-12 00:43:1611253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111254 TestCompletionCallback callback;
11255
tfarina42834112016-09-22 13:38:2011256 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111257 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111258 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111259}
11260
bncd16676a2016-07-20 16:23:0111261TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811262 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011264 HttpServerProperties* http_server_properties =
11265 session->http_server_properties();
bncb26024382016-06-29 02:39:4511266 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111267 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811268 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111269 http_server_properties->SetQuicAlternativeService(
11270 test_server, alternative_service, expiration,
11271 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411272 EXPECT_EQ(
11273 1u,
11274 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811275
11276 // Send a clear header.
11277 MockRead data_reads[] = {
11278 MockRead("HTTP/1.1 200 OK\r\n"),
11279 MockRead("Alt-Svc: clear\r\n"),
11280 MockRead("\r\n"),
11281 MockRead("hello world"),
11282 MockRead(SYNCHRONOUS, OK),
11283 };
11284 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
11285 session_deps_.socket_factory->AddSocketDataProvider(&data);
11286
bncb26024382016-06-29 02:39:4511287 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911288 ssl.ssl_info.cert =
11289 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11290 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511291 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11292
bnc4f575852015-10-14 18:35:0811293 HttpRequestInfo request;
11294 request.method = "GET";
bncb26024382016-06-29 02:39:4511295 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011296 request.traffic_annotation =
11297 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811298
11299 TestCompletionCallback callback;
11300
bnc691fda62016-08-12 00:43:1611301 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811302
tfarina42834112016-09-22 13:38:2011303 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111304 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811305
bnc691fda62016-08-12 00:43:1611306 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211307 ASSERT_TRUE(response);
11308 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811309 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11310 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211311 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811312
11313 std::string response_data;
bnc691fda62016-08-12 00:43:1611314 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811315 EXPECT_EQ("hello world", response_data);
11316
zhongyic4de03032017-05-19 04:07:3411317 EXPECT_TRUE(
11318 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811319}
11320
bncd16676a2016-07-20 16:23:0111321TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211322 MockRead data_reads[] = {
11323 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311324 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11325 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211326 MockRead("hello world"),
11327 MockRead(SYNCHRONOUS, OK),
11328 };
11329
11330 HttpRequestInfo request;
11331 request.method = "GET";
bncb26024382016-06-29 02:39:4511332 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011333 request.traffic_annotation =
11334 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211335
11336 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211337 session_deps_.socket_factory->AddSocketDataProvider(&data);
11338
bncb26024382016-06-29 02:39:4511339 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911340 ssl.ssl_info.cert =
11341 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11342 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511343 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11344
bncc958faa2015-07-31 18:14:5211345 TestCompletionCallback callback;
11346
danakj1fd259a02016-04-16 03:17:0911347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611348 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211349
tfarina42834112016-09-22 13:38:2011350 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211352
bncb26024382016-06-29 02:39:4511353 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011354 HttpServerProperties* http_server_properties =
11355 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411356 EXPECT_TRUE(
11357 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211358
robpercival214763f2016-07-01 23:27:0111359 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211360
bnc691fda62016-08-12 00:43:1611361 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211362 ASSERT_TRUE(response);
11363 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211364 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11365 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211366 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211367
11368 std::string response_data;
bnc691fda62016-08-12 00:43:1611369 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211370 EXPECT_EQ("hello world", response_data);
11371
zhongyic4de03032017-05-19 04:07:3411372 AlternativeServiceInfoVector alternative_service_info_vector =
11373 http_server_properties->GetAlternativeServiceInfos(test_server);
11374 ASSERT_EQ(2u, alternative_service_info_vector.size());
11375
11376 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11377 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411378 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411379 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11380 1234);
11381 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411382 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211383}
11384
bncd16676a2016-07-20 16:23:0111385TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611386 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211387 HostPortPair alternative("alternative.example.org", 443);
11388 std::string origin_url = "https://origin.example.org:443";
11389 std::string alternative_url = "https://alternative.example.org:443";
11390
11391 // Negotiate HTTP/1.1 with alternative.example.org.
11392 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611393 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211394 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11395
11396 // HTTP/1.1 data for request.
11397 MockWrite http_writes[] = {
11398 MockWrite("GET / HTTP/1.1\r\n"
11399 "Host: alternative.example.org\r\n"
11400 "Connection: keep-alive\r\n\r\n"),
11401 };
11402
11403 MockRead http_reads[] = {
11404 MockRead("HTTP/1.1 200 OK\r\n"
11405 "Content-Type: text/html; charset=iso-8859-1\r\n"
11406 "Content-Length: 40\r\n\r\n"
11407 "first HTTP/1.1 response from alternative"),
11408 };
11409 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11410 http_writes, arraysize(http_writes));
11411 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11412
11413 StaticSocketDataProvider data_refused;
11414 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11415 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11416
zhongyi3d4a55e72016-04-22 20:36:4611417 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011419 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211420 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111421 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211422 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111423 http_server_properties->SetQuicAlternativeService(
11424 server, alternative_service, expiration,
11425 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211426 // Mark the QUIC alternative service as broken.
11427 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11428
zhongyi48704c182015-12-07 07:52:0211429 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611430 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211431 request.method = "GET";
11432 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011433 request.traffic_annotation =
11434 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11435
zhongyi48704c182015-12-07 07:52:0211436 TestCompletionCallback callback;
11437 NetErrorDetails details;
11438 EXPECT_FALSE(details.quic_broken);
11439
tfarina42834112016-09-22 13:38:2011440 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611441 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211442 EXPECT_TRUE(details.quic_broken);
11443}
11444
bncd16676a2016-07-20 16:23:0111445TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611446 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211447 HostPortPair alternative1("alternative1.example.org", 443);
11448 HostPortPair alternative2("alternative2.example.org", 443);
11449 std::string origin_url = "https://origin.example.org:443";
11450 std::string alternative_url1 = "https://alternative1.example.org:443";
11451 std::string alternative_url2 = "https://alternative2.example.org:443";
11452
11453 // Negotiate HTTP/1.1 with alternative1.example.org.
11454 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611455 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11457
11458 // HTTP/1.1 data for request.
11459 MockWrite http_writes[] = {
11460 MockWrite("GET / HTTP/1.1\r\n"
11461 "Host: alternative1.example.org\r\n"
11462 "Connection: keep-alive\r\n\r\n"),
11463 };
11464
11465 MockRead http_reads[] = {
11466 MockRead("HTTP/1.1 200 OK\r\n"
11467 "Content-Type: text/html; charset=iso-8859-1\r\n"
11468 "Content-Length: 40\r\n\r\n"
11469 "first HTTP/1.1 response from alternative1"),
11470 };
11471 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11472 http_writes, arraysize(http_writes));
11473 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11474
11475 StaticSocketDataProvider data_refused;
11476 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11477 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11478
danakj1fd259a02016-04-16 03:17:0911479 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011480 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211481 session->http_server_properties();
11482
zhongyi3d4a55e72016-04-22 20:36:4611483 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211484 AlternativeServiceInfoVector alternative_service_info_vector;
11485 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11486
bnc3472afd2016-11-17 15:27:2111487 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111488 alternative_service_info_vector.push_back(
11489 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11490 alternative_service1, expiration,
11491 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111492 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111493 alternative_service_info_vector.push_back(
11494 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11495 alternative_service2, expiration,
11496 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211497
11498 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611499 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211500
11501 // Mark one of the QUIC alternative service as broken.
11502 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411503 EXPECT_EQ(2u,
11504 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211505
zhongyi48704c182015-12-07 07:52:0211506 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211508 request.method = "GET";
11509 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011510 request.traffic_annotation =
11511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11512
zhongyi48704c182015-12-07 07:52:0211513 TestCompletionCallback callback;
11514 NetErrorDetails details;
11515 EXPECT_FALSE(details.quic_broken);
11516
tfarina42834112016-09-22 13:38:2011517 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611518 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211519 EXPECT_FALSE(details.quic_broken);
11520}
11521
bncd16676a2016-07-20 16:23:0111522TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211523 HttpRequestInfo request;
11524 request.method = "GET";
bncb26024382016-06-29 02:39:4511525 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011526 request.traffic_annotation =
11527 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211528
[email protected]d973e99a2012-02-17 21:02:3611529 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211530 StaticSocketDataProvider first_data;
11531 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711532 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511533 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611534 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511535 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211536
11537 MockRead data_reads[] = {
11538 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11539 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611540 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211541 };
11542 StaticSocketDataProvider second_data(
11543 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711544 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211545
danakj1fd259a02016-04-16 03:17:0911546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211547
bnc525e175a2016-06-20 12:36:4011548 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311549 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611550 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111551 // Port must be < 1024, or the header will be ignored (since initial port was
11552 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111553 // Port is ignored by MockConnect anyway.
11554 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11555 666);
bnc7dc7e1b42015-07-28 14:43:1211556 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111557 http_server_properties->SetHttp2AlternativeService(
11558 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211559
bnc691fda62016-08-12 00:43:1611560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111561 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211562
tfarina42834112016-09-22 13:38:2011563 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11565 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211566
bnc691fda62016-08-12 00:43:1611567 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211568 ASSERT_TRUE(response);
11569 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211570 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11571
11572 std::string response_data;
bnc691fda62016-08-12 00:43:1611573 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211574 EXPECT_EQ("hello world", response_data);
11575
zhongyic4de03032017-05-19 04:07:3411576 const AlternativeServiceInfoVector alternative_service_info_vector =
11577 http_server_properties->GetAlternativeServiceInfos(server);
11578 ASSERT_EQ(1u, alternative_service_info_vector.size());
11579 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411580 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411581 EXPECT_TRUE(
11582 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211583}
11584
bnc55ff9da2015-08-19 18:42:3511585// Ensure that we are not allowed to redirect traffic via an alternate protocol
11586// to an unrestricted (port >= 1024) when the original traffic was on a
11587// restricted port (port < 1024). Ensure that we can redirect in all other
11588// cases.
bncd16676a2016-07-20 16:23:0111589TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111590 HttpRequestInfo restricted_port_request;
11591 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511592 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111593 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011594 restricted_port_request.traffic_annotation =
11595 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111596
[email protected]d973e99a2012-02-17 21:02:3611597 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111598 StaticSocketDataProvider first_data;
11599 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711600 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111601
11602 MockRead data_reads[] = {
11603 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11604 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611605 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111606 };
11607 StaticSocketDataProvider second_data(
11608 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711609 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511610 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611611 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111613
danakj1fd259a02016-04-16 03:17:0911614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111615
bnc525e175a2016-06-20 12:36:4011616 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311617 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111618 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111619 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11620 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211621 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111622 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611623 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011624 expiration);
[email protected]3912662a32011-10-04 00:51:1111625
bnc691fda62016-08-12 00:43:1611626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111627 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111628
tfarina42834112016-09-22 13:38:2011629 int rv = trans.Start(&restricted_port_request, callback.callback(),
11630 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111632 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111633 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911634}
[email protected]3912662a32011-10-04 00:51:1111635
bnc55ff9da2015-08-19 18:42:3511636// Ensure that we are allowed to redirect traffic via an alternate protocol to
11637// an unrestricted (port >= 1024) when the original traffic was on a restricted
11638// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111639TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711640 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911641
11642 HttpRequestInfo restricted_port_request;
11643 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511644 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911645 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011646 restricted_port_request.traffic_annotation =
11647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911648
11649 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11650 StaticSocketDataProvider first_data;
11651 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711652 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911653
11654 MockRead data_reads[] = {
11655 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11656 MockRead("hello world"),
11657 MockRead(ASYNC, OK),
11658 };
11659 StaticSocketDataProvider second_data(
11660 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711661 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511662 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611663 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911665
danakj1fd259a02016-04-16 03:17:0911666 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911667
bnc525e175a2016-06-20 12:36:4011668 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911669 session->http_server_properties();
11670 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111671 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11672 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211673 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111674 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611675 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011676 expiration);
[email protected]c54c6962013-02-01 04:53:1911677
bnc691fda62016-08-12 00:43:1611678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911679 TestCompletionCallback callback;
11680
tfarina42834112016-09-22 13:38:2011681 EXPECT_EQ(ERR_IO_PENDING,
11682 trans.Start(&restricted_port_request, callback.callback(),
11683 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911684 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111685 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111686}
11687
bnc55ff9da2015-08-19 18:42:3511688// Ensure that we are not allowed to redirect traffic via an alternate protocol
11689// to an unrestricted (port >= 1024) when the original traffic was on a
11690// restricted port (port < 1024). Ensure that we can redirect in all other
11691// cases.
bncd16676a2016-07-20 16:23:0111692TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111693 HttpRequestInfo restricted_port_request;
11694 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511695 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111696 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011697 restricted_port_request.traffic_annotation =
11698 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111699
[email protected]d973e99a2012-02-17 21:02:3611700 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111701 StaticSocketDataProvider first_data;
11702 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711703 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111704
11705 MockRead data_reads[] = {
11706 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11707 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611708 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111709 };
11710 StaticSocketDataProvider second_data(
11711 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711712 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111713
bncb26024382016-06-29 02:39:4511714 SSLSocketDataProvider ssl(ASYNC, OK);
11715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11716
danakj1fd259a02016-04-16 03:17:0911717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111718
bnc525e175a2016-06-20 12:36:4011719 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311720 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111721 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111722 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11723 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211724 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111725 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611726 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011727 expiration);
[email protected]3912662a32011-10-04 00:51:1111728
bnc691fda62016-08-12 00:43:1611729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111730 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111731
tfarina42834112016-09-22 13:38:2011732 int rv = trans.Start(&restricted_port_request, callback.callback(),
11733 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111735 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111736 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111737}
11738
bnc55ff9da2015-08-19 18:42:3511739// Ensure that we are not allowed to redirect traffic via an alternate protocol
11740// to an unrestricted (port >= 1024) when the original traffic was on a
11741// restricted port (port < 1024). Ensure that we can redirect in all other
11742// cases.
bncd16676a2016-07-20 16:23:0111743TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111744 HttpRequestInfo unrestricted_port_request;
11745 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511746 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111747 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011748 unrestricted_port_request.traffic_annotation =
11749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111750
[email protected]d973e99a2012-02-17 21:02:3611751 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111752 StaticSocketDataProvider first_data;
11753 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711754 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111755
11756 MockRead data_reads[] = {
11757 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11758 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611759 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111760 };
11761 StaticSocketDataProvider second_data(
11762 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711763 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511764 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611765 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111767
danakj1fd259a02016-04-16 03:17:0911768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111769
bnc525e175a2016-06-20 12:36:4011770 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311771 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111772 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111773 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11774 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211775 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111776 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611777 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011778 expiration);
[email protected]3912662a32011-10-04 00:51:1111779
bnc691fda62016-08-12 00:43:1611780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111781 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111782
bnc691fda62016-08-12 00:43:1611783 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011784 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111786 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111787 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111788}
11789
bnc55ff9da2015-08-19 18:42:3511790// Ensure that we are not allowed to redirect traffic via an alternate protocol
11791// to an unrestricted (port >= 1024) when the original traffic was on a
11792// restricted port (port < 1024). Ensure that we can redirect in all other
11793// cases.
bncd16676a2016-07-20 16:23:0111794TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111795 HttpRequestInfo unrestricted_port_request;
11796 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511797 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111798 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011799 unrestricted_port_request.traffic_annotation =
11800 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111801
[email protected]d973e99a2012-02-17 21:02:3611802 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111803 StaticSocketDataProvider first_data;
11804 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711805 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111806
11807 MockRead data_reads[] = {
11808 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11809 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611810 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111811 };
11812 StaticSocketDataProvider second_data(
11813 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711814 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111815
bncb26024382016-06-29 02:39:4511816 SSLSocketDataProvider ssl(ASYNC, OK);
11817 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11818
danakj1fd259a02016-04-16 03:17:0911819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111820
bnc525e175a2016-06-20 12:36:4011821 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311822 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211823 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111824 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11825 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211826 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111827 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611828 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011829 expiration);
[email protected]3912662a32011-10-04 00:51:1111830
bnc691fda62016-08-12 00:43:1611831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111832 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111833
bnc691fda62016-08-12 00:43:1611834 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011835 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111837 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111838 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111839}
11840
bnc55ff9da2015-08-19 18:42:3511841// Ensure that we are not allowed to redirect traffic via an alternate protocol
11842// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11843// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111844TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211845 HttpRequestInfo request;
11846 request.method = "GET";
bncce36dca22015-04-21 22:11:2311847 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011848 request.traffic_annotation =
11849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211850
11851 // The alternate protocol request will error out before we attempt to connect,
11852 // so only the standard HTTP request will try to connect.
11853 MockRead data_reads[] = {
11854 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11855 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611856 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211857 };
11858 StaticSocketDataProvider data(
11859 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711860 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211861
danakj1fd259a02016-04-16 03:17:0911862 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211863
bnc525e175a2016-06-20 12:36:4011864 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211865 session->http_server_properties();
11866 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111867 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11868 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211869 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111870 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611871 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211872
bnc691fda62016-08-12 00:43:1611873 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211874 TestCompletionCallback callback;
11875
tfarina42834112016-09-22 13:38:2011876 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211878 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111879 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211880
bnc691fda62016-08-12 00:43:1611881 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211882 ASSERT_TRUE(response);
11883 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211884 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11885
11886 std::string response_data;
bnc691fda62016-08-12 00:43:1611887 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211888 EXPECT_EQ("hello world", response_data);
11889}
11890
bncd16676a2016-07-20 16:23:0111891TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411892 HttpRequestInfo request;
11893 request.method = "GET";
bncb26024382016-06-29 02:39:4511894 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011895 request.traffic_annotation =
11896 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411897
11898 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211899 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311900 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211901 MockRead("\r\n"),
11902 MockRead("hello world"),
11903 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11904 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411905
11906 StaticSocketDataProvider first_transaction(
11907 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711908 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511909 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611910 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511911 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411912
bnc032658ba2016-09-26 18:17:1511913 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411914
bncdf80d44fd2016-07-15 20:27:4111915 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511916 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111917 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411918
bnc42331402016-07-25 13:36:1511919 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111920 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411921 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111922 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411923 };
11924
rch8e6c6c42015-05-01 14:05:1311925 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11926 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711927 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411928
[email protected]d973e99a2012-02-17 21:02:3611929 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511930 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11931 NULL, 0, NULL, 0);
11932 hanging_non_alternate_protocol_socket.set_connect_data(
11933 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711934 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511935 &hanging_non_alternate_protocol_socket);
11936
[email protected]49639fa2011-12-20 23:22:4111937 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411938
danakj1fd259a02016-04-16 03:17:0911939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811940 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911941 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411942
tfarina42834112016-09-22 13:38:2011943 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11945 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411946
11947 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211948 ASSERT_TRUE(response);
11949 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411950 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11951
11952 std::string response_data;
robpercival214763f2016-07-01 23:27:0111953 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411954 EXPECT_EQ("hello world", response_data);
11955
bnc87dcefc2017-05-25 12:47:5811956 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911957 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411958
tfarina42834112016-09-22 13:38:2011959 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111960 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11961 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411962
11963 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211964 ASSERT_TRUE(response);
11965 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211966 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311967 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211968 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411969
robpercival214763f2016-07-01 23:27:0111970 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411971 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411972}
11973
bncd16676a2016-07-20 16:23:0111974TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511975 HttpRequestInfo request;
11976 request.method = "GET";
bncb26024382016-06-29 02:39:4511977 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011978 request.traffic_annotation =
11979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511980
bncb26024382016-06-29 02:39:4511981 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511982 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211983 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311984 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211985 MockRead("\r\n"),
11986 MockRead("hello world"),
11987 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11988 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511989 };
11990
bncb26024382016-06-29 02:39:4511991 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11992 0);
11993 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511994
bncb26024382016-06-29 02:39:4511995 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911996 ssl_http11.ssl_info.cert =
11997 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11998 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511999 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12000
12001 // Second transaction starts an alternative and a non-alternative Job.
12002 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612003 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1812004 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
12005 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812006 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12007
12008 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
12009 hanging_socket2.set_connect_data(never_finishing_connect);
12010 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512011
bncb26024382016-06-29 02:39:4512012 // Third transaction starts an alternative and a non-alternative job.
12013 // The non-alternative job hangs, but the alternative one succeeds.
12014 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4112015 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512016 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112017 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512018 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512019 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112020 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512021 };
bnc42331402016-07-25 13:36:1512022 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112023 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512024 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112025 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512026 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112027 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12028 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312029 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512030 };
12031
rch8e6c6c42015-05-01 14:05:1312032 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12033 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712034 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512035
bnc032658ba2016-09-26 18:17:1512036 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512037
mmenkecc2298e2015-12-07 18:20:1812038 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
12039 hanging_socket3.set_connect_data(never_finishing_connect);
12040 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512041
danakj1fd259a02016-04-16 03:17:0912042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112043 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012044 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512045
tfarina42834112016-09-22 13:38:2012046 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12048 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512049
12050 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212051 ASSERT_TRUE(response);
12052 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512053 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12054
12055 std::string response_data;
robpercival214763f2016-07-01 23:27:0112056 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512057 EXPECT_EQ("hello world", response_data);
12058
[email protected]49639fa2011-12-20 23:22:4112059 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012060 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012061 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512063
[email protected]49639fa2011-12-20 23:22:4112064 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012065 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012066 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512068
robpercival214763f2016-07-01 23:27:0112069 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12070 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512071
12072 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212073 ASSERT_TRUE(response);
12074 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212075 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512076 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212077 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112078 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512079 EXPECT_EQ("hello!", response_data);
12080
12081 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212082 ASSERT_TRUE(response);
12083 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212084 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512085 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212086 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112087 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512088 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512089}
12090
bncd16676a2016-07-20 16:23:0112091TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512092 HttpRequestInfo request;
12093 request.method = "GET";
bncb26024382016-06-29 02:39:4512094 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012095 request.traffic_annotation =
12096 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512097
12098 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
12107 StaticSocketDataProvider first_transaction(
12108 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712109 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512110
[email protected]8ddf8322012-02-23 18:08:0612111 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912112 ssl.ssl_info.cert =
12113 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12114 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512116
[email protected]d973e99a2012-02-17 21:02:3612117 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512118 StaticSocketDataProvider hanging_alternate_protocol_socket(
12119 NULL, 0, NULL, 0);
12120 hanging_alternate_protocol_socket.set_connect_data(
12121 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712122 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512123 &hanging_alternate_protocol_socket);
12124
bncb26024382016-06-29 02:39:4512125 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1812126 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
12127 NULL, 0);
12128 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512129 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512130
[email protected]49639fa2011-12-20 23:22:4112131 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512132
danakj1fd259a02016-04-16 03:17:0912133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812134 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912135 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512136
tfarina42834112016-09-22 13:38:2012137 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12139 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512140
12141 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212142 ASSERT_TRUE(response);
12143 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512144 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12145
12146 std::string response_data;
robpercival214763f2016-07-01 23:27:0112147 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512148 EXPECT_EQ("hello world", response_data);
12149
bnc87dcefc2017-05-25 12:47:5812150 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912151 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512152
tfarina42834112016-09-22 13:38:2012153 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12155 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512156
12157 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212158 ASSERT_TRUE(response);
12159 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512160 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12161 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212162 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512163
robpercival214763f2016-07-01 23:27:0112164 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512165 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512166}
12167
[email protected]631f1322010-04-30 17:59:1112168class CapturingProxyResolver : public ProxyResolver {
12169 public:
Chris Watkins7a41d3552017-12-01 02:13:2712170 CapturingProxyResolver() = default;
12171 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112172
dchengb03027d2014-10-21 12:00:2012173 int GetProxyForURL(const GURL& url,
12174 ProxyInfo* results,
12175 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512176 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012177 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012178 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12179 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212180 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112181 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212182 return OK;
[email protected]631f1322010-04-30 17:59:1112183 }
12184
[email protected]24476402010-07-20 20:55:1712185 const std::vector<GURL>& resolved() const { return resolved_; }
12186
12187 private:
[email protected]631f1322010-04-30 17:59:1112188 std::vector<GURL> resolved_;
12189
12190 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12191};
12192
sammce64b2362015-04-29 03:50:2312193class CapturingProxyResolverFactory : public ProxyResolverFactory {
12194 public:
12195 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12196 : ProxyResolverFactory(false), resolver_(resolver) {}
12197
Lily Houghton99597862018-03-07 16:40:4212198 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12199 std::unique_ptr<ProxyResolver>* resolver,
12200 const net::CompletionCallback& callback,
12201 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912202 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312203 return OK;
12204 }
12205
12206 private:
12207 ProxyResolver* resolver_;
12208};
12209
bnc2e884782016-08-11 19:45:1912210// Test that proxy is resolved using the origin url,
12211// regardless of the alternative server.
12212TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12213 // Configure proxy to bypass www.example.org, which is the origin URL.
12214 ProxyConfig proxy_config;
12215 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12216 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912217 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12218 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912219
12220 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912221 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912222 &capturing_proxy_resolver);
12223
12224 TestNetLog net_log;
12225
Lily Houghton8c2f97d2018-01-22 05:06:5912226 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1912227 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12228 &net_log);
12229
12230 session_deps_.net_log = &net_log;
12231
12232 // Configure alternative service with a hostname that is not bypassed by the
12233 // proxy.
12234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12235 HttpServerProperties* http_server_properties =
12236 session->http_server_properties();
12237 url::SchemeHostPort server("https", "www.example.org", 443);
12238 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112239 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912240 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112241 http_server_properties->SetHttp2AlternativeService(
12242 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912243
12244 // Non-alternative job should hang.
12245 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
12246 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
12247 nullptr, 0);
12248 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12249 session_deps_.socket_factory->AddSocketDataProvider(
12250 &hanging_alternate_protocol_socket);
12251
bnc032658ba2016-09-26 18:17:1512252 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912253
12254 HttpRequestInfo request;
12255 request.method = "GET";
12256 request.url = GURL("https://www.example.org/");
12257 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012258 request.traffic_annotation =
12259 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912260
12261 SpdySerializedFrame req(
12262 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12263
12264 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12265
12266 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12267 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12268 MockRead spdy_reads[] = {
12269 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12270 };
12271
12272 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12273 arraysize(spdy_writes));
12274 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12275
12276 TestCompletionCallback callback;
12277
12278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12279
tfarina42834112016-09-22 13:38:2012280 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912281 EXPECT_THAT(callback.GetResult(rv), IsOk());
12282
12283 const HttpResponseInfo* response = trans.GetResponseInfo();
12284 ASSERT_TRUE(response);
12285 ASSERT_TRUE(response->headers);
12286 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12287 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212288 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912289
12290 std::string response_data;
12291 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12292 EXPECT_EQ("hello!", response_data);
12293
12294 // Origin host bypasses proxy, no resolution should have happened.
12295 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12296}
12297
bncd16676a2016-07-20 16:23:0112298TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112299 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212300 proxy_config.set_auto_detect(true);
12301 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112302
sammc5dd160c2015-04-02 02:43:1312303 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912304 session_deps_.proxy_resolution_service =
12305 std::make_unique<ProxyResolutionService>(
12306 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12307 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12308 std::make_unique<CapturingProxyResolverFactory>(
12309 &capturing_proxy_resolver),
12310 nullptr);
vishal.b62985ca92015-04-17 08:45:5112311 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712312 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112313
12314 HttpRequestInfo request;
12315 request.method = "GET";
bncb26024382016-06-29 02:39:4512316 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012317 request.traffic_annotation =
12318 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112319
12320 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212321 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312322 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212323 MockRead("\r\n"),
12324 MockRead("hello world"),
12325 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12326 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112327 };
12328
12329 StaticSocketDataProvider first_transaction(
12330 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712331 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512332 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612333 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112335
bnc032658ba2016-09-26 18:17:1512336 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112337
bncdf80d44fd2016-07-15 20:27:4112338 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512339 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112340 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312341 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512342 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12343 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312344 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112345 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112346 };
12347
[email protected]d911f1b2010-05-05 22:39:4212348 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12349
bnc42331402016-07-25 13:36:1512350 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112351 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112352 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112353 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12354 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112355 };
12356
rch8e6c6c42015-05-01 14:05:1312357 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12358 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712359 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112360
[email protected]d973e99a2012-02-17 21:02:3612361 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512362 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12363 NULL, 0, NULL, 0);
12364 hanging_non_alternate_protocol_socket.set_connect_data(
12365 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712366 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512367 &hanging_non_alternate_protocol_socket);
12368
[email protected]49639fa2011-12-20 23:22:4112369 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112370
danakj1fd259a02016-04-16 03:17:0912371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812372 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912373 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112374
tfarina42834112016-09-22 13:38:2012375 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12377 EXPECT_THAT(callback.WaitForResult(), IsOk());
12378
12379 const HttpResponseInfo* response = trans->GetResponseInfo();
12380 ASSERT_TRUE(response);
12381 ASSERT_TRUE(response->headers);
12382 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12383 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212384 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112385
12386 std::string response_data;
12387 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12388 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112389
bnc87dcefc2017-05-25 12:47:5812390 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912391 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112392
tfarina42834112016-09-22 13:38:2012393 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12395 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112396
mmenkea2dcd3bf2016-08-16 21:49:4112397 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212398 ASSERT_TRUE(response);
12399 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212400 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312401 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212402 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112403
robpercival214763f2016-07-01 23:27:0112404 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112405 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512406 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12407 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312408 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312409 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312410 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112411
[email protected]029c83b62013-01-24 05:28:2012412 LoadTimingInfo load_timing_info;
12413 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12414 TestLoadTimingNotReusedWithPac(load_timing_info,
12415 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112416}
[email protected]631f1322010-04-30 17:59:1112417
bncd16676a2016-07-20 16:23:0112418TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812419 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412420 HttpRequestInfo request;
12421 request.method = "GET";
bncb26024382016-06-29 02:39:4512422 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012423 request.traffic_annotation =
12424 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412425
12426 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212427 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312428 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212429 MockRead("\r\n"),
12430 MockRead("hello world"),
12431 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412432 };
12433
12434 StaticSocketDataProvider first_transaction(
12435 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712436 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512437 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612438 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512439 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412440
bnc032658ba2016-09-26 18:17:1512441 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412442
bncdf80d44fd2016-07-15 20:27:4112443 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512444 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112445 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412446
bnc42331402016-07-25 13:36:1512447 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112448 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412449 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112450 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412451 };
12452
rch8e6c6c42015-05-01 14:05:1312453 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12454 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712455 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412456
[email protected]83039bb2011-12-09 18:43:5512457 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412458
danakj1fd259a02016-04-16 03:17:0912459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412460
bnc87dcefc2017-05-25 12:47:5812461 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912462 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412463
tfarina42834112016-09-22 13:38:2012464 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12466 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412467
12468 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212469 ASSERT_TRUE(response);
12470 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412471 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12472
12473 std::string response_data;
robpercival214763f2016-07-01 23:27:0112474 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412475 EXPECT_EQ("hello world", response_data);
12476
12477 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512478 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012479 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412480 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712481 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212482 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812483
bnc87dcefc2017-05-25 12:47:5812484 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912485 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412486
tfarina42834112016-09-22 13:38:2012487 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12489 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412490
12491 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212492 ASSERT_TRUE(response);
12493 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212494 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312495 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212496 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412497
robpercival214763f2016-07-01 23:27:0112498 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412499 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212500}
12501
[email protected]044de0642010-06-17 10:42:1512502// GenerateAuthToken is a mighty big test.
12503// It tests all permutation of GenerateAuthToken behavior:
12504// - Synchronous and Asynchronous completion.
12505// - OK or error on completion.
12506// - Direct connection, non-authenticating proxy, and authenticating proxy.
12507// - HTTP or HTTPS backend (to include proxy tunneling).
12508// - Non-authenticating and authenticating backend.
12509//
[email protected]fe3b7dc2012-02-03 19:52:0912510// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512511// problems generating an auth token for an authenticating proxy, we don't
12512// need to test all permutations of the backend server).
12513//
12514// The test proceeds by going over each of the configuration cases, and
12515// potentially running up to three rounds in each of the tests. The TestConfig
12516// specifies both the configuration for the test as well as the expectations
12517// for the results.
bncd16676a2016-07-20 16:23:0112518TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012519 static const char kServer[] = "http://www.example.com";
12520 static const char kSecureServer[] = "https://www.example.com";
12521 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512522
12523 enum AuthTiming {
12524 AUTH_NONE,
12525 AUTH_SYNC,
12526 AUTH_ASYNC,
12527 };
12528
12529 const MockWrite kGet(
12530 "GET / HTTP/1.1\r\n"
12531 "Host: www.example.com\r\n"
12532 "Connection: keep-alive\r\n\r\n");
12533 const MockWrite kGetProxy(
12534 "GET http://www.example.com/ HTTP/1.1\r\n"
12535 "Host: www.example.com\r\n"
12536 "Proxy-Connection: keep-alive\r\n\r\n");
12537 const MockWrite kGetAuth(
12538 "GET / HTTP/1.1\r\n"
12539 "Host: www.example.com\r\n"
12540 "Connection: keep-alive\r\n"
12541 "Authorization: auth_token\r\n\r\n");
12542 const MockWrite kGetProxyAuth(
12543 "GET http://www.example.com/ HTTP/1.1\r\n"
12544 "Host: www.example.com\r\n"
12545 "Proxy-Connection: keep-alive\r\n"
12546 "Proxy-Authorization: auth_token\r\n\r\n");
12547 const MockWrite kGetAuthThroughProxy(
12548 "GET http://www.example.com/ HTTP/1.1\r\n"
12549 "Host: www.example.com\r\n"
12550 "Proxy-Connection: keep-alive\r\n"
12551 "Authorization: auth_token\r\n\r\n");
12552 const MockWrite kGetAuthWithProxyAuth(
12553 "GET http://www.example.com/ HTTP/1.1\r\n"
12554 "Host: www.example.com\r\n"
12555 "Proxy-Connection: keep-alive\r\n"
12556 "Proxy-Authorization: auth_token\r\n"
12557 "Authorization: auth_token\r\n\r\n");
12558 const MockWrite kConnect(
12559 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712560 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512561 "Proxy-Connection: keep-alive\r\n\r\n");
12562 const MockWrite kConnectProxyAuth(
12563 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712564 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512565 "Proxy-Connection: keep-alive\r\n"
12566 "Proxy-Authorization: auth_token\r\n\r\n");
12567
12568 const MockRead kSuccess(
12569 "HTTP/1.1 200 OK\r\n"
12570 "Content-Type: text/html; charset=iso-8859-1\r\n"
12571 "Content-Length: 3\r\n\r\n"
12572 "Yes");
12573 const MockRead kFailure(
12574 "Should not be called.");
12575 const MockRead kServerChallenge(
12576 "HTTP/1.1 401 Unauthorized\r\n"
12577 "WWW-Authenticate: Mock realm=server\r\n"
12578 "Content-Type: text/html; charset=iso-8859-1\r\n"
12579 "Content-Length: 14\r\n\r\n"
12580 "Unauthorized\r\n");
12581 const MockRead kProxyChallenge(
12582 "HTTP/1.1 407 Unauthorized\r\n"
12583 "Proxy-Authenticate: Mock realm=proxy\r\n"
12584 "Proxy-Connection: close\r\n"
12585 "Content-Type: text/html; charset=iso-8859-1\r\n"
12586 "Content-Length: 14\r\n\r\n"
12587 "Unauthorized\r\n");
12588 const MockRead kProxyConnected(
12589 "HTTP/1.1 200 Connection Established\r\n\r\n");
12590
12591 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12592 // no constructors, but the C++ compiler on Windows warns about
12593 // unspecified data in compound literals. So, moved to using constructors,
12594 // and TestRound's created with the default constructor should not be used.
12595 struct TestRound {
12596 TestRound()
12597 : expected_rv(ERR_UNEXPECTED),
12598 extra_write(NULL),
12599 extra_read(NULL) {
12600 }
12601 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12602 int expected_rv_arg)
12603 : write(write_arg),
12604 read(read_arg),
12605 expected_rv(expected_rv_arg),
12606 extra_write(NULL),
12607 extra_read(NULL) {
12608 }
12609 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12610 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112611 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512612 : write(write_arg),
12613 read(read_arg),
12614 expected_rv(expected_rv_arg),
12615 extra_write(extra_write_arg),
12616 extra_read(extra_read_arg) {
12617 }
12618 MockWrite write;
12619 MockRead read;
12620 int expected_rv;
12621 const MockWrite* extra_write;
12622 const MockRead* extra_read;
12623 };
12624
12625 static const int kNoSSL = 500;
12626
12627 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112628 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112629 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512630 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112631 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112632 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512633 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112634 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512635 int num_auth_rounds;
12636 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612637 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512638 } test_configs[] = {
asankac93076192016-10-03 15:46:0212639 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112640 {__LINE__,
12641 nullptr,
asankac93076192016-10-03 15:46:0212642 AUTH_NONE,
12643 OK,
12644 kServer,
12645 AUTH_NONE,
12646 OK,
12647 1,
12648 kNoSSL,
12649 {TestRound(kGet, kSuccess, OK)}},
12650 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112651 {__LINE__,
12652 nullptr,
asankac93076192016-10-03 15:46:0212653 AUTH_NONE,
12654 OK,
12655 kServer,
12656 AUTH_SYNC,
12657 OK,
12658 2,
12659 kNoSSL,
12660 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512661 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112662 {__LINE__,
12663 nullptr,
asankac93076192016-10-03 15:46:0212664 AUTH_NONE,
12665 OK,
12666 kServer,
12667 AUTH_SYNC,
12668 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612669 3,
12670 kNoSSL,
12671 {TestRound(kGet, kServerChallenge, OK),
12672 TestRound(kGet, kServerChallenge, OK),
12673 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112674 {__LINE__,
12675 nullptr,
asankae2257db2016-10-11 22:03:1612676 AUTH_NONE,
12677 OK,
12678 kServer,
12679 AUTH_SYNC,
12680 ERR_UNSUPPORTED_AUTH_SCHEME,
12681 2,
12682 kNoSSL,
12683 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112684 {__LINE__,
12685 nullptr,
asankae2257db2016-10-11 22:03:1612686 AUTH_NONE,
12687 OK,
12688 kServer,
12689 AUTH_SYNC,
12690 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12691 2,
12692 kNoSSL,
12693 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112694 {__LINE__,
12695 kProxy,
asankae2257db2016-10-11 22:03:1612696 AUTH_SYNC,
12697 ERR_FAILED,
12698 kServer,
12699 AUTH_NONE,
12700 OK,
12701 2,
12702 kNoSSL,
12703 {TestRound(kGetProxy, kProxyChallenge, OK),
12704 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112705 {__LINE__,
12706 kProxy,
asankae2257db2016-10-11 22:03:1612707 AUTH_ASYNC,
12708 ERR_FAILED,
12709 kServer,
12710 AUTH_NONE,
12711 OK,
12712 2,
12713 kNoSSL,
12714 {TestRound(kGetProxy, kProxyChallenge, OK),
12715 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112716 {__LINE__,
12717 nullptr,
asankae2257db2016-10-11 22:03:1612718 AUTH_NONE,
12719 OK,
12720 kServer,
12721 AUTH_SYNC,
12722 ERR_FAILED,
asankac93076192016-10-03 15:46:0212723 2,
12724 kNoSSL,
12725 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612726 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112727 {__LINE__,
12728 nullptr,
asankae2257db2016-10-11 22:03:1612729 AUTH_NONE,
12730 OK,
12731 kServer,
12732 AUTH_ASYNC,
12733 ERR_FAILED,
12734 2,
12735 kNoSSL,
12736 {TestRound(kGet, kServerChallenge, OK),
12737 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112738 {__LINE__,
12739 nullptr,
asankac93076192016-10-03 15:46:0212740 AUTH_NONE,
12741 OK,
12742 kServer,
12743 AUTH_ASYNC,
12744 OK,
12745 2,
12746 kNoSSL,
12747 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512748 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112749 {__LINE__,
12750 nullptr,
asankac93076192016-10-03 15:46:0212751 AUTH_NONE,
12752 OK,
12753 kServer,
12754 AUTH_ASYNC,
12755 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612756 3,
asankac93076192016-10-03 15:46:0212757 kNoSSL,
12758 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612759 // The second round uses a HttpAuthHandlerMock that always succeeds.
12760 TestRound(kGet, kServerChallenge, OK),
12761 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212762 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112763 {__LINE__,
12764 kProxy,
asankac93076192016-10-03 15:46:0212765 AUTH_NONE,
12766 OK,
12767 kServer,
12768 AUTH_NONE,
12769 OK,
12770 1,
12771 kNoSSL,
12772 {TestRound(kGetProxy, kSuccess, OK)}},
12773 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112774 {__LINE__,
12775 kProxy,
asankac93076192016-10-03 15:46:0212776 AUTH_NONE,
12777 OK,
12778 kServer,
12779 AUTH_SYNC,
12780 OK,
12781 2,
12782 kNoSSL,
12783 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512784 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112785 {__LINE__,
12786 kProxy,
asankac93076192016-10-03 15:46:0212787 AUTH_NONE,
12788 OK,
12789 kServer,
12790 AUTH_SYNC,
12791 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612792 3,
asankac93076192016-10-03 15:46:0212793 kNoSSL,
12794 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612795 TestRound(kGetProxy, kServerChallenge, OK),
12796 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112797 {__LINE__,
12798 kProxy,
asankac93076192016-10-03 15:46:0212799 AUTH_NONE,
12800 OK,
12801 kServer,
12802 AUTH_ASYNC,
12803 OK,
12804 2,
12805 kNoSSL,
12806 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512807 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112808 {__LINE__,
12809 kProxy,
asankac93076192016-10-03 15:46:0212810 AUTH_NONE,
12811 OK,
12812 kServer,
12813 AUTH_ASYNC,
12814 ERR_INVALID_AUTH_CREDENTIALS,
12815 2,
12816 kNoSSL,
12817 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612818 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212819 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112820 {__LINE__,
12821 kProxy,
asankac93076192016-10-03 15:46:0212822 AUTH_SYNC,
12823 OK,
12824 kServer,
12825 AUTH_NONE,
12826 OK,
12827 2,
12828 kNoSSL,
12829 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512830 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112831 {__LINE__,
12832 kProxy,
asankac93076192016-10-03 15:46:0212833 AUTH_SYNC,
12834 ERR_INVALID_AUTH_CREDENTIALS,
12835 kServer,
12836 AUTH_NONE,
12837 OK,
12838 2,
12839 kNoSSL,
12840 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612841 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112842 {__LINE__,
12843 kProxy,
asankac93076192016-10-03 15:46:0212844 AUTH_ASYNC,
12845 OK,
12846 kServer,
12847 AUTH_NONE,
12848 OK,
12849 2,
12850 kNoSSL,
12851 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512852 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112853 {__LINE__,
12854 kProxy,
asankac93076192016-10-03 15:46:0212855 AUTH_ASYNC,
12856 ERR_INVALID_AUTH_CREDENTIALS,
12857 kServer,
12858 AUTH_NONE,
12859 OK,
12860 2,
12861 kNoSSL,
12862 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612863 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112864 {__LINE__,
12865 kProxy,
12866 AUTH_ASYNC,
12867 ERR_INVALID_AUTH_CREDENTIALS,
12868 kServer,
12869 AUTH_NONE,
12870 OK,
12871 3,
12872 kNoSSL,
12873 {TestRound(kGetProxy, kProxyChallenge, OK),
12874 TestRound(kGetProxy, kProxyChallenge, OK),
12875 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212876 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112877 {__LINE__,
12878 kProxy,
asankac93076192016-10-03 15:46:0212879 AUTH_SYNC,
12880 OK,
12881 kServer,
12882 AUTH_SYNC,
12883 OK,
12884 3,
12885 kNoSSL,
12886 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512887 TestRound(kGetProxyAuth, kServerChallenge, OK),
12888 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112889 {__LINE__,
12890 kProxy,
asankac93076192016-10-03 15:46:0212891 AUTH_SYNC,
12892 OK,
12893 kServer,
12894 AUTH_SYNC,
12895 ERR_INVALID_AUTH_CREDENTIALS,
12896 3,
12897 kNoSSL,
12898 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512899 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612900 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112901 {__LINE__,
12902 kProxy,
asankac93076192016-10-03 15:46:0212903 AUTH_ASYNC,
12904 OK,
12905 kServer,
12906 AUTH_SYNC,
12907 OK,
12908 3,
12909 kNoSSL,
12910 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512911 TestRound(kGetProxyAuth, kServerChallenge, OK),
12912 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112913 {__LINE__,
12914 kProxy,
asankac93076192016-10-03 15:46:0212915 AUTH_ASYNC,
12916 OK,
12917 kServer,
12918 AUTH_SYNC,
12919 ERR_INVALID_AUTH_CREDENTIALS,
12920 3,
12921 kNoSSL,
12922 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512923 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612924 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112925 {__LINE__,
12926 kProxy,
asankac93076192016-10-03 15:46:0212927 AUTH_SYNC,
12928 OK,
12929 kServer,
12930 AUTH_ASYNC,
12931 OK,
12932 3,
12933 kNoSSL,
12934 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512935 TestRound(kGetProxyAuth, kServerChallenge, OK),
12936 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112937 {__LINE__,
12938 kProxy,
12939 AUTH_SYNC,
12940 ERR_INVALID_AUTH_CREDENTIALS,
12941 kServer,
12942 AUTH_ASYNC,
12943 OK,
12944 4,
12945 kNoSSL,
12946 {TestRound(kGetProxy, kProxyChallenge, OK),
12947 TestRound(kGetProxy, kProxyChallenge, OK),
12948 TestRound(kGetProxyAuth, kServerChallenge, OK),
12949 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12950 {__LINE__,
12951 kProxy,
asankac93076192016-10-03 15:46:0212952 AUTH_SYNC,
12953 OK,
12954 kServer,
12955 AUTH_ASYNC,
12956 ERR_INVALID_AUTH_CREDENTIALS,
12957 3,
12958 kNoSSL,
12959 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512960 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612961 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112962 {__LINE__,
12963 kProxy,
asankac93076192016-10-03 15:46:0212964 AUTH_ASYNC,
12965 OK,
12966 kServer,
12967 AUTH_ASYNC,
12968 OK,
12969 3,
12970 kNoSSL,
12971 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512972 TestRound(kGetProxyAuth, kServerChallenge, OK),
12973 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112974 {__LINE__,
12975 kProxy,
asankac93076192016-10-03 15:46:0212976 AUTH_ASYNC,
12977 OK,
12978 kServer,
12979 AUTH_ASYNC,
12980 ERR_INVALID_AUTH_CREDENTIALS,
12981 3,
12982 kNoSSL,
12983 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512984 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612985 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112986 {__LINE__,
12987 kProxy,
12988 AUTH_ASYNC,
12989 ERR_INVALID_AUTH_CREDENTIALS,
12990 kServer,
12991 AUTH_ASYNC,
12992 ERR_INVALID_AUTH_CREDENTIALS,
12993 4,
12994 kNoSSL,
12995 {TestRound(kGetProxy, kProxyChallenge, OK),
12996 TestRound(kGetProxy, kProxyChallenge, OK),
12997 TestRound(kGetProxyAuth, kServerChallenge, OK),
12998 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212999 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113000 {__LINE__,
13001 nullptr,
asankac93076192016-10-03 15:46:0213002 AUTH_NONE,
13003 OK,
13004 kSecureServer,
13005 AUTH_NONE,
13006 OK,
13007 1,
13008 0,
13009 {TestRound(kGet, kSuccess, OK)}},
13010 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113011 {__LINE__,
13012 nullptr,
asankac93076192016-10-03 15:46:0213013 AUTH_NONE,
13014 OK,
13015 kSecureServer,
13016 AUTH_SYNC,
13017 OK,
13018 2,
13019 0,
13020 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513021 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113022 {__LINE__,
13023 nullptr,
asankac93076192016-10-03 15:46:0213024 AUTH_NONE,
13025 OK,
13026 kSecureServer,
13027 AUTH_SYNC,
13028 ERR_INVALID_AUTH_CREDENTIALS,
13029 2,
13030 0,
asankae2257db2016-10-11 22:03:1613031 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113032 {__LINE__,
13033 nullptr,
asankac93076192016-10-03 15:46:0213034 AUTH_NONE,
13035 OK,
13036 kSecureServer,
13037 AUTH_ASYNC,
13038 OK,
13039 2,
13040 0,
13041 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513042 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113043 {__LINE__,
13044 nullptr,
asankac93076192016-10-03 15:46:0213045 AUTH_NONE,
13046 OK,
13047 kSecureServer,
13048 AUTH_ASYNC,
13049 ERR_INVALID_AUTH_CREDENTIALS,
13050 2,
13051 0,
asankae2257db2016-10-11 22:03:1613052 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213053 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113054 {__LINE__,
13055 kProxy,
asankac93076192016-10-03 15:46:0213056 AUTH_NONE,
13057 OK,
13058 kSecureServer,
13059 AUTH_NONE,
13060 OK,
13061 1,
13062 0,
13063 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13064 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113065 {__LINE__,
13066 kProxy,
asankac93076192016-10-03 15:46:0213067 AUTH_NONE,
13068 OK,
13069 kSecureServer,
13070 AUTH_SYNC,
13071 OK,
13072 2,
13073 0,
13074 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513075 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113076 {__LINE__,
13077 kProxy,
asankac93076192016-10-03 15:46:0213078 AUTH_NONE,
13079 OK,
13080 kSecureServer,
13081 AUTH_SYNC,
13082 ERR_INVALID_AUTH_CREDENTIALS,
13083 2,
13084 0,
13085 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613086 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113087 {__LINE__,
13088 kProxy,
asankac93076192016-10-03 15:46:0213089 AUTH_NONE,
13090 OK,
13091 kSecureServer,
13092 AUTH_ASYNC,
13093 OK,
13094 2,
13095 0,
13096 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513097 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113098 {__LINE__,
13099 kProxy,
asankac93076192016-10-03 15:46:0213100 AUTH_NONE,
13101 OK,
13102 kSecureServer,
13103 AUTH_ASYNC,
13104 ERR_INVALID_AUTH_CREDENTIALS,
13105 2,
13106 0,
13107 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613108 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213109 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113110 {__LINE__,
13111 kProxy,
asankac93076192016-10-03 15:46:0213112 AUTH_SYNC,
13113 OK,
13114 kSecureServer,
13115 AUTH_NONE,
13116 OK,
13117 2,
13118 1,
13119 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513120 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113121 {__LINE__,
13122 kProxy,
asankac93076192016-10-03 15:46:0213123 AUTH_SYNC,
13124 ERR_INVALID_AUTH_CREDENTIALS,
13125 kSecureServer,
13126 AUTH_NONE,
13127 OK,
13128 2,
13129 kNoSSL,
13130 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613131 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113132 {__LINE__,
13133 kProxy,
asankae2257db2016-10-11 22:03:1613134 AUTH_SYNC,
13135 ERR_UNSUPPORTED_AUTH_SCHEME,
13136 kSecureServer,
13137 AUTH_NONE,
13138 OK,
13139 2,
13140 kNoSSL,
13141 {TestRound(kConnect, kProxyChallenge, OK),
13142 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113143 {__LINE__,
13144 kProxy,
asankae2257db2016-10-11 22:03:1613145 AUTH_SYNC,
13146 ERR_UNEXPECTED,
13147 kSecureServer,
13148 AUTH_NONE,
13149 OK,
13150 2,
13151 kNoSSL,
13152 {TestRound(kConnect, kProxyChallenge, OK),
13153 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113154 {__LINE__,
13155 kProxy,
asankac93076192016-10-03 15:46:0213156 AUTH_ASYNC,
13157 OK,
13158 kSecureServer,
13159 AUTH_NONE,
13160 OK,
13161 2,
13162 1,
13163 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513164 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113165 {__LINE__,
13166 kProxy,
asankac93076192016-10-03 15:46:0213167 AUTH_ASYNC,
13168 ERR_INVALID_AUTH_CREDENTIALS,
13169 kSecureServer,
13170 AUTH_NONE,
13171 OK,
13172 2,
13173 kNoSSL,
13174 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613175 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213176 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113177 {__LINE__,
13178 kProxy,
asankac93076192016-10-03 15:46:0213179 AUTH_SYNC,
13180 OK,
13181 kSecureServer,
13182 AUTH_SYNC,
13183 OK,
13184 3,
13185 1,
13186 {TestRound(kConnect, kProxyChallenge, OK),
13187 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13188 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513189 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113190 {__LINE__,
13191 kProxy,
asankac93076192016-10-03 15:46:0213192 AUTH_SYNC,
13193 OK,
13194 kSecureServer,
13195 AUTH_SYNC,
13196 ERR_INVALID_AUTH_CREDENTIALS,
13197 3,
13198 1,
13199 {TestRound(kConnect, kProxyChallenge, OK),
13200 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13201 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613202 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113203 {__LINE__,
13204 kProxy,
asankac93076192016-10-03 15:46:0213205 AUTH_ASYNC,
13206 OK,
13207 kSecureServer,
13208 AUTH_SYNC,
13209 OK,
13210 3,
13211 1,
13212 {TestRound(kConnect, kProxyChallenge, OK),
13213 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13214 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513215 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113216 {__LINE__,
13217 kProxy,
asankac93076192016-10-03 15:46:0213218 AUTH_ASYNC,
13219 OK,
13220 kSecureServer,
13221 AUTH_SYNC,
13222 ERR_INVALID_AUTH_CREDENTIALS,
13223 3,
13224 1,
13225 {TestRound(kConnect, kProxyChallenge, OK),
13226 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13227 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613228 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113229 {__LINE__,
13230 kProxy,
asankac93076192016-10-03 15:46:0213231 AUTH_SYNC,
13232 OK,
13233 kSecureServer,
13234 AUTH_ASYNC,
13235 OK,
13236 3,
13237 1,
13238 {TestRound(kConnect, kProxyChallenge, OK),
13239 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13240 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513241 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113242 {__LINE__,
13243 kProxy,
asankac93076192016-10-03 15:46:0213244 AUTH_SYNC,
13245 OK,
13246 kSecureServer,
13247 AUTH_ASYNC,
13248 ERR_INVALID_AUTH_CREDENTIALS,
13249 3,
13250 1,
13251 {TestRound(kConnect, kProxyChallenge, OK),
13252 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13253 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613254 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113255 {__LINE__,
13256 kProxy,
asankac93076192016-10-03 15:46:0213257 AUTH_ASYNC,
13258 OK,
13259 kSecureServer,
13260 AUTH_ASYNC,
13261 OK,
13262 3,
13263 1,
13264 {TestRound(kConnect, kProxyChallenge, OK),
13265 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13266 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513267 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113268 {__LINE__,
13269 kProxy,
asankac93076192016-10-03 15:46:0213270 AUTH_ASYNC,
13271 OK,
13272 kSecureServer,
13273 AUTH_ASYNC,
13274 ERR_INVALID_AUTH_CREDENTIALS,
13275 3,
13276 1,
13277 {TestRound(kConnect, kProxyChallenge, OK),
13278 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13279 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613280 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113281 {__LINE__,
13282 kProxy,
13283 AUTH_ASYNC,
13284 ERR_INVALID_AUTH_CREDENTIALS,
13285 kSecureServer,
13286 AUTH_ASYNC,
13287 ERR_INVALID_AUTH_CREDENTIALS,
13288 4,
13289 2,
13290 {TestRound(kConnect, kProxyChallenge, OK),
13291 TestRound(kConnect, kProxyChallenge, OK),
13292 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13293 &kServerChallenge),
13294 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513295 };
13296
asanka463ca4262016-11-16 02:34:3113297 for (const auto& test_config : test_configs) {
13298 SCOPED_TRACE(::testing::Message() << "Test config at "
13299 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813300 HttpAuthHandlerMock::Factory* auth_factory(
13301 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713302 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913303 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613304
13305 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513306 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113307 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813308 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13309 std::string auth_challenge = "Mock realm=proxy";
13310 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413311 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13312 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813313 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013314 empty_ssl_info, origin,
13315 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813316 auth_handler->SetGenerateExpectation(
13317 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113318 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813319 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13320 }
[email protected]044de0642010-06-17 10:42:1513321 }
13322 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013323 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513324 std::string auth_challenge = "Mock realm=server";
13325 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413326 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13327 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513328 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013329 empty_ssl_info, origin,
13330 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513331 auth_handler->SetGenerateExpectation(
13332 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113333 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813334 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613335
13336 // The second handler always succeeds. It should only be used where there
13337 // are multiple auth sessions for server auth in the same network
13338 // transaction using the same auth scheme.
13339 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913340 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613341 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13342 empty_ssl_info, origin,
13343 NetLogWithSource());
13344 second_handler->SetGenerateExpectation(true, OK);
13345 auth_factory->AddMockHandler(second_handler.release(),
13346 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513347 }
13348 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913349 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913350 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13351 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513352 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913353 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513354 }
13355
13356 HttpRequestInfo request;
13357 request.method = "GET";
13358 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1013359 request.traffic_annotation =
13360 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513361
danakj1fd259a02016-04-16 03:17:0913362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513363
rchcb68dc62015-05-21 04:45:3613364 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13365
13366 std::vector<std::vector<MockRead>> mock_reads(1);
13367 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513368 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213369 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513370 const TestRound& read_write_round = test_config.rounds[round];
13371
13372 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613373 mock_reads.back().push_back(read_write_round.read);
13374 mock_writes.back().push_back(read_write_round.write);
13375
13376 // kProxyChallenge uses Proxy-Connection: close which means that the
13377 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413378 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613379 mock_reads.push_back(std::vector<MockRead>());
13380 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513381 }
13382
rchcb68dc62015-05-21 04:45:3613383 if (read_write_round.extra_read) {
13384 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513385 }
rchcb68dc62015-05-21 04:45:3613386 if (read_write_round.extra_write) {
13387 mock_writes.back().push_back(*read_write_round.extra_write);
13388 }
[email protected]044de0642010-06-17 10:42:1513389
13390 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513391 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713392 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513393 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613394 }
[email protected]044de0642010-06-17 10:42:1513395
danakj1fd259a02016-04-16 03:17:0913396 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613397 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913398 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413399 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813400 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613401 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213402 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613403 }
13404
mmenkecc2298e2015-12-07 18:20:1813405 // Transaction must be created after DataProviders, so it's destroyed before
13406 // they are as well.
13407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13408
rchcb68dc62015-05-21 04:45:3613409 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213410 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613411 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513412 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113413 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513414 int rv;
13415 if (round == 0) {
tfarina42834112016-09-22 13:38:2013416 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513417 } else {
[email protected]49639fa2011-12-20 23:22:4113418 rv = trans.RestartWithAuth(
13419 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513420 }
13421 if (rv == ERR_IO_PENDING)
13422 rv = callback.WaitForResult();
13423
13424 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613425 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013426 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513427 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513428 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13429 continue;
13430 }
13431 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213432 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513433 } else {
wezca1070932016-05-26 20:30:5213434 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613435 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513436 }
13437 }
[email protected]e5ae96a2010-04-14 20:12:4513438 }
13439}
13440
bncd16676a2016-07-20 16:23:0113441TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413442 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413443 HttpAuthHandlerMock::Factory* auth_factory(
13444 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713445 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913446 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713447 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13448 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413449
13450 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13451 auth_handler->set_connection_based(true);
13452 std::string auth_challenge = "Mock realm=server";
13453 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413454 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13455 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913456 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413457 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013458 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813459 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413460
[email protected]c871bce92010-07-15 21:51:1413461 int rv = OK;
13462 const HttpResponseInfo* response = NULL;
13463 HttpRequestInfo request;
13464 request.method = "GET";
13465 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1013466 request.traffic_annotation =
13467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713468
danakj1fd259a02016-04-16 03:17:0913469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013470
13471 // Use a TCP Socket Pool with only one connection per group. This is used
13472 // to validate that the TCP socket is not released to the pool between
13473 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213474 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813475 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013476 50, // Max sockets for pool
13477 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113478 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13479 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913480 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213481 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813482 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013483
bnc691fda62016-08-12 00:43:1613484 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113485 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413486
13487 const MockWrite kGet(
13488 "GET / HTTP/1.1\r\n"
13489 "Host: www.example.com\r\n"
13490 "Connection: keep-alive\r\n\r\n");
13491 const MockWrite kGetAuth(
13492 "GET / HTTP/1.1\r\n"
13493 "Host: www.example.com\r\n"
13494 "Connection: keep-alive\r\n"
13495 "Authorization: auth_token\r\n\r\n");
13496
13497 const MockRead kServerChallenge(
13498 "HTTP/1.1 401 Unauthorized\r\n"
13499 "WWW-Authenticate: Mock realm=server\r\n"
13500 "Content-Type: text/html; charset=iso-8859-1\r\n"
13501 "Content-Length: 14\r\n\r\n"
13502 "Unauthorized\r\n");
13503 const MockRead kSuccess(
13504 "HTTP/1.1 200 OK\r\n"
13505 "Content-Type: text/html; charset=iso-8859-1\r\n"
13506 "Content-Length: 3\r\n\r\n"
13507 "Yes");
13508
13509 MockWrite writes[] = {
13510 // First round
13511 kGet,
13512 // Second round
13513 kGetAuth,
13514 // Third round
13515 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013516 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013517 kGetAuth,
13518 // Competing request
13519 kGet,
[email protected]c871bce92010-07-15 21:51:1413520 };
13521 MockRead reads[] = {
13522 // First round
13523 kServerChallenge,
13524 // Second round
13525 kServerChallenge,
13526 // Third round
[email protected]eca50e122010-09-11 14:03:3013527 kServerChallenge,
13528 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413529 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013530 // Competing response
13531 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413532 };
13533 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13534 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713535 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413536
thestig9d3bb0c2015-01-24 00:49:5113537 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013538
13539 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413540 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013541 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413542 if (rv == ERR_IO_PENDING)
13543 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113544 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613545 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213546 ASSERT_TRUE(response);
13547 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813548 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113549 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13550 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413551
[email protected]7ef4cbbb2011-02-06 11:19:1013552 // In between rounds, another request comes in for the same domain.
13553 // It should not be able to grab the TCP socket that trans has already
13554 // claimed.
bnc691fda62016-08-12 00:43:1613555 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113556 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013557 rv = trans_compete.Start(&request, callback_compete.callback(),
13558 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013560 // callback_compete.WaitForResult at this point would stall forever,
13561 // since the HttpNetworkTransaction does not release the request back to
13562 // the pool until after authentication completes.
13563
13564 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413565 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613566 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413567 if (rv == ERR_IO_PENDING)
13568 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113569 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613570 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213571 ASSERT_TRUE(response);
13572 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813573 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113574 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13575 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413576
[email protected]7ef4cbbb2011-02-06 11:19:1013577 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413578 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613579 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413580 if (rv == ERR_IO_PENDING)
13581 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113582 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613583 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213584 ASSERT_TRUE(response);
13585 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813586 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113587 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13588 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013589
[email protected]7ef4cbbb2011-02-06 11:19:1013590 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013591 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613592 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013593 if (rv == ERR_IO_PENDING)
13594 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113595 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613596 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213597 ASSERT_TRUE(response);
13598 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813599 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013600
asanka463ca4262016-11-16 02:34:3113601 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13602 // auth handler should transition to a DONE state in concert with the remote
13603 // server. But that's not something we can test here with a mock handler.
13604 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13605 auth_handler->state());
13606
[email protected]7ef4cbbb2011-02-06 11:19:1013607 // Read the body since the fourth round was successful. This will also
13608 // release the socket back to the pool.
13609 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613610 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013611 if (rv == ERR_IO_PENDING)
13612 rv = callback.WaitForResult();
13613 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613614 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013615 EXPECT_EQ(0, rv);
13616 // There are still 0 idle sockets, since the trans_compete transaction
13617 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813618 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013619
13620 // The competing request can now finish. Wait for the headers and then
13621 // read the body.
13622 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113623 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613624 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013625 if (rv == ERR_IO_PENDING)
13626 rv = callback.WaitForResult();
13627 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613628 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013629 EXPECT_EQ(0, rv);
13630
13631 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813632 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413633}
13634
[email protected]65041fa2010-05-21 06:56:5313635// This tests the case that a request is issued via http instead of spdy after
13636// npn is negotiated.
bncd16676a2016-07-20 16:23:0113637TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313638 HttpRequestInfo request;
13639 request.method = "GET";
bncce36dca22015-04-21 22:11:2313640 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013641 request.traffic_annotation =
13642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313643
13644 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313645 MockWrite(
13646 "GET / HTTP/1.1\r\n"
13647 "Host: www.example.org\r\n"
13648 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313649 };
13650
13651 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213652 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313653 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213654 MockRead("\r\n"),
13655 MockRead("hello world"),
13656 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313657 };
13658
[email protected]8ddf8322012-02-23 18:08:0613659 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613660 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313661
[email protected]bb88e1d32013-05-03 23:11:0713662 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313663
13664 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13665 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713666 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313667
[email protected]49639fa2011-12-20 23:22:4113668 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313669
danakj1fd259a02016-04-16 03:17:0913670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313672
tfarina42834112016-09-22 13:38:2013673 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313674
robpercival214763f2016-07-01 23:27:0113675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13676 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313677
bnc691fda62016-08-12 00:43:1613678 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213679 ASSERT_TRUE(response);
13680 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313681 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13682
13683 std::string response_data;
bnc691fda62016-08-12 00:43:1613684 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313685 EXPECT_EQ("hello world", response_data);
13686
13687 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213688 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313689}
[email protected]26ef6582010-06-24 02:30:4713690
bnc55ff9da2015-08-19 18:42:3513691// Simulate the SSL handshake completing with an NPN negotiation followed by an
13692// immediate server closing of the socket.
13693// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113694TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713695 HttpRequestInfo request;
13696 request.method = "GET";
bncce36dca22015-04-21 22:11:2313697 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013698 request.traffic_annotation =
13699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713700
[email protected]8ddf8322012-02-23 18:08:0613701 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613702 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713704
Bence Béky27ad0a12018-02-08 00:35:4813705 SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113706 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713707
13708 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613709 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713710 };
13711
rch8e6c6c42015-05-01 14:05:1313712 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13713 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713714 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713715
[email protected]49639fa2011-12-20 23:22:4113716 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713717
danakj1fd259a02016-04-16 03:17:0913718 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613719 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713720
tfarina42834112016-09-22 13:38:2013721 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113722 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13723 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713724}
[email protected]65d34382010-07-01 18:12:2613725
[email protected]795cbf82013-07-22 09:37:2713726// A subclass of HttpAuthHandlerMock that records the request URL when
13727// it gets it. This is needed since the auth handler may get destroyed
13728// before we get a chance to query it.
13729class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13730 public:
13731 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13732
Chris Watkins7a41d3552017-12-01 02:13:2713733 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713734
13735 protected:
dchengb03027d2014-10-21 12:00:2013736 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13737 const HttpRequestInfo* request,
13738 const CompletionCallback& callback,
13739 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713740 *url_ = request->url;
13741 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13742 credentials, request, callback, auth_token);
13743 }
13744
13745 private:
13746 GURL* url_;
13747};
13748
[email protected]8e6441ca2010-08-19 05:56:3813749// Test that if we cancel the transaction as the connection is completing, that
13750// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113751TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813752 // Setup everything about the connection to complete synchronously, so that
13753 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13754 // for is the callback from the HttpStreamRequest.
13755 // Then cancel the transaction.
13756 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613757 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813758 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613759 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13760 MockRead(SYNCHRONOUS, "hello world"),
13761 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813762 };
13763
[email protected]8e6441ca2010-08-19 05:56:3813764 HttpRequestInfo request;
13765 request.method = "GET";
bncce36dca22015-04-21 22:11:2313766 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013767 request.traffic_annotation =
13768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813769
[email protected]bb88e1d32013-05-03 23:11:0713770 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913771 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813772 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913773 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713774
[email protected]8e6441ca2010-08-19 05:56:3813775 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13776 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713777 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813778
[email protected]49639fa2011-12-20 23:22:4113779 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813780
vishal.b62985ca92015-04-17 08:45:5113781 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113782 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813784 trans.reset(); // Cancel the transaction here.
13785
fdoray92e35a72016-06-10 15:54:5513786 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013787}
13788
[email protected]ecab6e052014-05-16 14:58:1213789// Test that if a transaction is cancelled after receiving the headers, the
13790// stream is drained properly and added back to the socket pool. The main
13791// purpose of this test is to make sure that an HttpStreamParser can be read
13792// from after the HttpNetworkTransaction and the objects it owns have been
13793// deleted.
13794// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113795TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213796 MockRead data_reads[] = {
13797 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13798 MockRead(ASYNC, "Content-Length: 2\r\n"),
13799 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13800 MockRead(ASYNC, "1"),
13801 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13802 // HttpNetworkTransaction has been deleted.
13803 MockRead(ASYNC, "2"),
13804 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13805 };
13806 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13807 session_deps_.socket_factory->AddSocketDataProvider(&data);
13808
danakj1fd259a02016-04-16 03:17:0913809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213810
13811 {
13812 HttpRequestInfo request;
13813 request.method = "GET";
bncce36dca22015-04-21 22:11:2313814 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013815 request.traffic_annotation =
13816 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213817
dcheng48459ac22014-08-26 00:46:4113818 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213819 TestCompletionCallback callback;
13820
tfarina42834112016-09-22 13:38:2013821 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213823 callback.WaitForResult();
13824
13825 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213826 ASSERT_TRUE(response);
13827 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213828 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13829
13830 // The transaction and HttpRequestInfo are deleted.
13831 }
13832
13833 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513834 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213835
13836 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113837 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213838}
13839
[email protected]76a505b2010-08-25 06:23:0013840// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113841TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913842 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913843 ProxyResolutionService::CreateFixedFromPacResult(
13844 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113845 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713846 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013848
[email protected]76a505b2010-08-25 06:23:0013849 HttpRequestInfo request;
13850 request.method = "GET";
bncce36dca22015-04-21 22:11:2313851 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013852 request.traffic_annotation =
13853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013854
13855 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313856 MockWrite(
13857 "GET http://www.example.org/ HTTP/1.1\r\n"
13858 "Host: www.example.org\r\n"
13859 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013860 };
13861
13862 MockRead data_reads1[] = {
13863 MockRead("HTTP/1.1 200 OK\r\n"),
13864 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13865 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613866 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013867 };
13868
13869 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13870 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013872
[email protected]49639fa2011-12-20 23:22:4113873 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013874
bnc691fda62016-08-12 00:43:1613875 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913876 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613877 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913878 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13879 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013880
bnc691fda62016-08-12 00:43:1613881 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013883
13884 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113885 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013886
bnc691fda62016-08-12 00:43:1613887 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213888 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013889
13890 EXPECT_TRUE(response->headers->IsKeepAlive());
13891 EXPECT_EQ(200, response->headers->response_code());
13892 EXPECT_EQ(100, response->headers->GetContentLength());
13893 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713894 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13895 HostPortPair::FromString("myproxy:70")),
13896 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913897 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13898 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13899 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013900 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013901
13902 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613903 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013904 TestLoadTimingNotReusedWithPac(load_timing_info,
13905 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013906}
13907
13908// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113909TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913910 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913911 ProxyResolutionService::CreateFixedFromPacResult(
13912 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113913 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713914 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013916
[email protected]76a505b2010-08-25 06:23:0013917 HttpRequestInfo request;
13918 request.method = "GET";
bncce36dca22015-04-21 22:11:2313919 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013920 request.traffic_annotation =
13921 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013922
13923 // Since we have proxy, should try to establish tunnel.
13924 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713925 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13926 "Host: www.example.org:443\r\n"
13927 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013928
rsleevidb16bb02015-11-12 23:47:1713929 MockWrite("GET / HTTP/1.1\r\n"
13930 "Host: www.example.org\r\n"
13931 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013932 };
13933
13934 MockRead data_reads1[] = {
13935 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13936
13937 MockRead("HTTP/1.1 200 OK\r\n"),
13938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13939 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613940 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013941 };
13942
13943 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13944 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613946 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713947 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013948
[email protected]49639fa2011-12-20 23:22:4113949 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013950
bnc691fda62016-08-12 00:43:1613951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913952 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613953 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913954 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13955 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013956
bnc691fda62016-08-12 00:43:1613957 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013959
13960 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113961 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613962 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013963 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013964 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013965 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13966 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013967 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013968 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013969 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13970 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013971
bnc691fda62016-08-12 00:43:1613972 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213973 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013974
13975 EXPECT_TRUE(response->headers->IsKeepAlive());
13976 EXPECT_EQ(200, response->headers->response_code());
13977 EXPECT_EQ(100, response->headers->GetContentLength());
13978 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13979 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713980 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13981 HostPortPair::FromString("myproxy:70")),
13982 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913983 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13984 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13985 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013986
13987 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613988 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013989 TestLoadTimingNotReusedWithPac(load_timing_info,
13990 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013991}
13992
rsleevidb16bb02015-11-12 23:47:1713993// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13994// literal host.
bncd16676a2016-07-20 16:23:0113995TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913996 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913997 ProxyResolutionService::CreateFixedFromPacResult(
13998 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713999 BoundTestNetLog log;
14000 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714002
14003 HttpRequestInfo request;
14004 request.method = "GET";
14005 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1014006 request.traffic_annotation =
14007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714008
14009 // Since we have proxy, should try to establish tunnel.
14010 MockWrite data_writes1[] = {
14011 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
14012 "Host: [::1]:443\r\n"
14013 "Proxy-Connection: keep-alive\r\n\r\n"),
14014
14015 MockWrite("GET / HTTP/1.1\r\n"
14016 "Host: [::1]\r\n"
14017 "Connection: keep-alive\r\n\r\n"),
14018 };
14019
14020 MockRead data_reads1[] = {
14021 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14022
14023 MockRead("HTTP/1.1 200 OK\r\n"),
14024 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14025 MockRead("Content-Length: 100\r\n\r\n"),
14026 MockRead(SYNCHRONOUS, OK),
14027 };
14028
14029 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14030 data_writes1, arraysize(data_writes1));
14031 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14032 SSLSocketDataProvider ssl(ASYNC, OK);
14033 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14034
14035 TestCompletionCallback callback1;
14036
bnc691fda62016-08-12 00:43:1614037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714038
bnc691fda62016-08-12 00:43:1614039 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714041
14042 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114043 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714044 TestNetLogEntry::List entries;
14045 log.GetEntries(&entries);
14046 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014047 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14048 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714049 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014050 entries, pos,
14051 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14052 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714053
bnc691fda62016-08-12 00:43:1614054 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214055 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714056
14057 EXPECT_TRUE(response->headers->IsKeepAlive());
14058 EXPECT_EQ(200, response->headers->response_code());
14059 EXPECT_EQ(100, response->headers->GetContentLength());
14060 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14061 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714062 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14063 HostPortPair::FromString("myproxy:70")),
14064 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714065
14066 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614067 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714068 TestLoadTimingNotReusedWithPac(load_timing_info,
14069 CONNECT_TIMING_HAS_SSL_TIMES);
14070}
14071
[email protected]76a505b2010-08-25 06:23:0014072// Test a basic HTTPS GET request through a proxy, but the server hangs up
14073// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114074TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914075 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14076 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114077 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714078 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014080
[email protected]76a505b2010-08-25 06:23:0014081 HttpRequestInfo request;
14082 request.method = "GET";
bncce36dca22015-04-21 22:11:2314083 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014084 request.traffic_annotation =
14085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014086
14087 // Since we have proxy, should try to establish tunnel.
14088 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714089 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14090 "Host: www.example.org:443\r\n"
14091 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014092
rsleevidb16bb02015-11-12 23:47:1714093 MockWrite("GET / HTTP/1.1\r\n"
14094 "Host: www.example.org\r\n"
14095 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014096 };
14097
14098 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014099 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614100 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014101 };
14102
14103 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14104 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714105 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614106 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714107 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014108
[email protected]49639fa2011-12-20 23:22:4114109 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014110
bnc691fda62016-08-12 00:43:1614111 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014112
bnc691fda62016-08-12 00:43:1614113 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014115
14116 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114117 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614118 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014119 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014120 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014121 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14122 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014123 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014124 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014125 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14126 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014127}
14128
[email protected]749eefa82010-09-13 22:14:0314129// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114130TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114131 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914132 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114133 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314134
bnc42331402016-07-25 13:36:1514135 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114136 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314137 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114138 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314139 };
14140
rch8e6c6c42015-05-01 14:05:1314141 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
14142 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714143 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314144
[email protected]8ddf8322012-02-23 18:08:0614145 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614146 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314148
danakj1fd259a02016-04-16 03:17:0914149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314150
14151 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314152 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014153 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414154 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714155 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214156 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314157
14158 HttpRequestInfo request;
14159 request.method = "GET";
bncce36dca22015-04-21 22:11:2314160 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014161 request.traffic_annotation =
14162 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314163
14164 // This is the important line that marks this as a preconnect.
14165 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14166
bnc691fda62016-08-12 00:43:1614167 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314168
[email protected]41d64e82013-07-03 22:44:2614169 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014170 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14172 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314173}
14174
[email protected]73b8dd222010-11-11 19:55:2414175// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614176// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214177void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714178 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914179 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714180 request_info.url = GURL("https://www.example.com/");
14181 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914182 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014183 request_info.traffic_annotation =
14184 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714185
[email protected]8ddf8322012-02-23 18:08:0614186 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914187 MockWrite data_writes[] = {
14188 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414189 };
ttuttle859dc7a2015-04-23 19:42:2914190 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0714191 session_deps_.socket_factory->AddSocketDataProvider(&data);
14192 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414193
danakj1fd259a02016-04-16 03:17:0914194 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614195 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414196
[email protected]49639fa2011-12-20 23:22:4114197 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014198 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914199 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414200 rv = callback.WaitForResult();
14201 ASSERT_EQ(error, rv);
14202}
14203
bncd16676a2016-07-20 16:23:0114204TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414205 // Just check a grab bag of cert errors.
14206 static const int kErrors[] = {
14207 ERR_CERT_COMMON_NAME_INVALID,
14208 ERR_CERT_AUTHORITY_INVALID,
14209 ERR_CERT_DATE_INVALID,
14210 };
14211 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614212 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14213 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414214 }
14215}
14216
[email protected]bd0b6772011-01-11 19:59:3014217// Ensure that a client certificate is removed from the SSL client auth
14218// cache when:
14219// 1) No proxy is involved.
14220// 2) TLS False Start is disabled.
14221// 3) The initial TLS handshake requests a client certificate.
14222// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114223TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914224 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714225 request_info.url = GURL("https://www.example.com/");
14226 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914227 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014228 request_info.traffic_annotation =
14229 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714230
[email protected]bd0b6772011-01-11 19:59:3014231 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114232 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014233
14234 // [ssl_]data1 contains the data for the first SSL handshake. When a
14235 // CertificateRequest is received for the first time, the handshake will
14236 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914237 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014238 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714239 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914240 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714241 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014242
14243 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14244 // False Start is not being used, the result of the SSL handshake will be
14245 // returned as part of the SSLClientSocket::Connect() call. This test
14246 // matches the result of a server sending a handshake_failure alert,
14247 // rather than a Finished message, because it requires a client
14248 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914249 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014250 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914252 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714253 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014254
14255 // [ssl_]data3 contains the data for the third SSL handshake. When a
14256 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214257 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14258 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014259 // of the HttpNetworkTransaction. Because this test failure is due to
14260 // requiring a client certificate, this fallback handshake should also
14261 // fail.
ttuttle859dc7a2015-04-23 19:42:2914262 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014263 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914265 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714266 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014267
[email protected]80c75f682012-05-26 16:22:1714268 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14269 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214270 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14271 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714272 // of the HttpNetworkTransaction. Because this test failure is due to
14273 // requiring a client certificate, this fallback handshake should also
14274 // fail.
ttuttle859dc7a2015-04-23 19:42:2914275 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714276 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714277 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914278 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714279 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714280
danakj1fd259a02016-04-16 03:17:0914281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614282 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014283
[email protected]bd0b6772011-01-11 19:59:3014284 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114285 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014286 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114287 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014288
14289 // Complete the SSL handshake, which should abort due to requiring a
14290 // client certificate.
14291 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114292 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014293
14294 // Indicate that no certificate should be supplied. From the perspective
14295 // of SSLClientCertCache, NULL is just as meaningful as a real
14296 // certificate, so this is the same as supply a
14297 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614298 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114299 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014300
14301 // Ensure the certificate was added to the client auth cache before
14302 // allowing the connection to continue restarting.
14303 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414304 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114305 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414306 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214307 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014308
14309 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714310 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14311 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014312 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114313 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014314
14315 // Ensure that the client certificate is removed from the cache on a
14316 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114317 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414318 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014319}
14320
14321// Ensure that a client certificate is removed from the SSL client auth
14322// cache when:
14323// 1) No proxy is involved.
14324// 2) TLS False Start is enabled.
14325// 3) The initial TLS handshake requests a client certificate.
14326// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114327TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914328 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714329 request_info.url = GURL("https://www.example.com/");
14330 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914331 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014332 request_info.traffic_annotation =
14333 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714334
[email protected]bd0b6772011-01-11 19:59:3014335 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114336 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014337
14338 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14339 // return successfully after reading up to the peer's Certificate message.
14340 // This is to allow the caller to call SSLClientSocket::Write(), which can
14341 // enqueue application data to be sent in the same packet as the
14342 // ChangeCipherSpec and Finished messages.
14343 // The actual handshake will be finished when SSLClientSocket::Read() is
14344 // called, which expects to process the peer's ChangeCipherSpec and
14345 // Finished messages. If there was an error negotiating with the peer,
14346 // such as due to the peer requiring a client certificate when none was
14347 // supplied, the alert sent by the peer won't be processed until Read() is
14348 // called.
14349
14350 // Like the non-False Start case, when a client certificate is requested by
14351 // the peer, the handshake is aborted during the Connect() call.
14352 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914353 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014354 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714355 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914356 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714357 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014358
14359 // When a client certificate is supplied, Connect() will not be aborted
14360 // when the peer requests the certificate. Instead, the handshake will
14361 // artificially succeed, allowing the caller to write the HTTP request to
14362 // the socket. The handshake messages are not processed until Read() is
14363 // called, which then detects that the handshake was aborted, due to the
14364 // peer sending a handshake_failure because it requires a client
14365 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914366 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014367 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914369 MockRead data2_reads[] = {
14370 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014371 };
ttuttle859dc7a2015-04-23 19:42:2914372 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714373 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014374
14375 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714376 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14377 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914378 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014379 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914381 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714382 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014383
[email protected]80c75f682012-05-26 16:22:1714384 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14385 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914386 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714387 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914389 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714390 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714391
[email protected]7799de12013-05-30 05:52:5114392 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914393 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114394 ssl_data5.cert_request_info = cert_request.get();
14395 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914396 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114397 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14398
danakj1fd259a02016-04-16 03:17:0914399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014401
[email protected]bd0b6772011-01-11 19:59:3014402 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114403 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014404 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114405 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014406
14407 // Complete the SSL handshake, which should abort due to requiring a
14408 // client certificate.
14409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114410 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014411
14412 // Indicate that no certificate should be supplied. From the perspective
14413 // of SSLClientCertCache, NULL is just as meaningful as a real
14414 // certificate, so this is the same as supply a
14415 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614416 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114417 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014418
14419 // Ensure the certificate was added to the client auth cache before
14420 // allowing the connection to continue restarting.
14421 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414422 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114423 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414424 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214425 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014426
[email protected]bd0b6772011-01-11 19:59:3014427 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714428 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14429 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014430 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114431 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014432
14433 // Ensure that the client certificate is removed from the cache on a
14434 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114435 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414436 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014437}
14438
[email protected]8c405132011-01-11 22:03:1814439// Ensure that a client certificate is removed from the SSL client auth
14440// cache when:
14441// 1) An HTTPS proxy is involved.
14442// 3) The HTTPS proxy requests a client certificate.
14443// 4) The client supplies an invalid/unacceptable certificate for the
14444// proxy.
14445// The test is repeated twice, first for connecting to an HTTPS endpoint,
14446// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114447TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914448 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14449 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114450 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714451 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814452
14453 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114454 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814455
14456 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14457 // [ssl_]data[1-3]. Rather than represending the endpoint
14458 // (www.example.com:443), they represent failures with the HTTPS proxy
14459 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914460 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814461 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914463 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714464 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814465
ttuttle859dc7a2015-04-23 19:42:2914466 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814467 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914469 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714470 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814471
[email protected]80c75f682012-05-26 16:22:1714472 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14473#if 0
ttuttle859dc7a2015-04-23 19:42:2914474 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814475 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914477 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714478 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714479#endif
[email protected]8c405132011-01-11 22:03:1814480
ttuttle859dc7a2015-04-23 19:42:2914481 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814482 requests[0].url = GURL("https://www.example.com/");
14483 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914484 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014485 requests[0].traffic_annotation =
14486 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814487
14488 requests[1].url = GURL("http://www.example.com/");
14489 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914490 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014491 requests[1].traffic_annotation =
14492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814493
14494 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714495 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814498
14499 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114500 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014501 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114502 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814503
14504 // Complete the SSL handshake, which should abort due to requiring a
14505 // client certificate.
14506 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114507 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814508
14509 // Indicate that no certificate should be supplied. From the perspective
14510 // of SSLClientCertCache, NULL is just as meaningful as a real
14511 // certificate, so this is the same as supply a
14512 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614513 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114514 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814515
14516 // Ensure the certificate was added to the client auth cache before
14517 // allowing the connection to continue restarting.
14518 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414519 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114520 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414521 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214522 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814523 // Ensure the certificate was NOT cached for the endpoint. This only
14524 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114525 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414526 HostPortPair("www.example.com", 443), &client_cert,
14527 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814528
14529 // Restart the handshake. This will consume ssl_data2, which fails, and
14530 // then consume ssl_data3, which should also fail. The result code is
14531 // checked against what ssl_data3 should return.
14532 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114533 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814534
14535 // Now that the new handshake has failed, ensure that the client
14536 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114537 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414538 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114539 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414540 HostPortPair("www.example.com", 443), &client_cert,
14541 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814542 }
14543}
14544
bncd16676a2016-07-20 16:23:0114545TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614546 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914547 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614549
bnc032658ba2016-09-26 18:17:1514550 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614551
bncdf80d44fd2016-07-15 20:27:4114552 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914553 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814554 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114555 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714556 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614557 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114558 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614559 };
bnc42331402016-07-25 13:36:1514560 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114561 SpdySerializedFrame host1_resp_body(
14562 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514563 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114564 SpdySerializedFrame host2_resp_body(
14565 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614566 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114567 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14568 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314569 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614570 };
14571
eroman36d84e54432016-03-17 03:23:0214572 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214573 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314574 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14575 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714576 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614577
[email protected]aa22b242011-11-16 18:58:2914578 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614579 HttpRequestInfo request1;
14580 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314581 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614582 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014583 request1.traffic_annotation =
14584 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014585 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614586
tfarina42834112016-09-22 13:38:2014587 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114588 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14589 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614590
14591 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214592 ASSERT_TRUE(response);
14593 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214594 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614595
14596 std::string response_data;
robpercival214763f2016-07-01 23:27:0114597 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614598 EXPECT_EQ("hello!", response_data);
14599
bnca4d611d2016-09-22 19:55:3714600 // Preload mail.example.com into HostCache.
14601 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014602 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614603 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014604 std::unique_ptr<HostResolver::Request> request;
14605 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14606 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014607 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114608 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714609 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114610 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614611
14612 HttpRequestInfo request2;
14613 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714614 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614615 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014616 request2.traffic_annotation =
14617 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014618 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614619
tfarina42834112016-09-22 13:38:2014620 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14622 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614623
14624 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214625 ASSERT_TRUE(response);
14626 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214627 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614628 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214629 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114630 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614631 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614632}
14633
bncd16676a2016-07-20 16:23:0114634TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214635 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914636 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214638
bnc032658ba2016-09-26 18:17:1514639 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214640
bncdf80d44fd2016-07-15 20:27:4114641 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914642 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814643 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114644 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714645 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214646 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114647 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214648 };
bnc42331402016-07-25 13:36:1514649 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114650 SpdySerializedFrame host1_resp_body(
14651 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514652 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114653 SpdySerializedFrame host2_resp_body(
14654 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214655 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114656 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14657 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314658 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214659 };
14660
eroman36d84e54432016-03-17 03:23:0214661 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214662 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314663 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14664 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714665 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214666
14667 TestCompletionCallback callback;
14668 HttpRequestInfo request1;
14669 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314670 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214671 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014672 request1.traffic_annotation =
14673 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014674 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214675
tfarina42834112016-09-22 13:38:2014676 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14678 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214679
14680 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214681 ASSERT_TRUE(response);
14682 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214683 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214684
14685 std::string response_data;
robpercival214763f2016-07-01 23:27:0114686 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214687 EXPECT_EQ("hello!", response_data);
14688
14689 HttpRequestInfo request2;
14690 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714691 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214692 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014693 request2.traffic_annotation =
14694 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014695 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214696
tfarina42834112016-09-22 13:38:2014697 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14699 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214700
14701 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214702 ASSERT_TRUE(response);
14703 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214704 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214705 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214706 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114707 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214708 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214709}
14710
bnc8016c1f2017-03-31 02:11:2914711// Regression test for https://crbug.com/546991.
14712// The server might not be able to serve an IP pooled request, and might send a
14713// 421 Misdirected Request response status to indicate this.
14714// HttpNetworkTransaction should reset the request and retry without IP pooling.
14715TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14716 // Two hosts resolve to the same IP address.
14717 const std::string ip_addr = "1.2.3.4";
14718 IPAddress ip;
14719 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14720 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14721
Jeremy Roman0579ed62017-08-29 15:56:1914722 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914723 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14724 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14725
14726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14727
14728 // Two requests on the first connection.
14729 SpdySerializedFrame req1(
14730 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14731 spdy_util_.UpdateWithStreamDestruction(1);
14732 SpdySerializedFrame req2(
14733 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14734 SpdySerializedFrame rst(
14735 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14736 MockWrite writes1[] = {
14737 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14738 CreateMockWrite(rst, 6),
14739 };
14740
14741 // The first one succeeds, the second gets error 421 Misdirected Request.
14742 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14743 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14744 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714745 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914746 SpdySerializedFrame resp2(
14747 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14748 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14749 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14750
14751 MockConnect connect1(ASYNC, OK, peer_addr);
14752 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14753 arraysize(writes1));
14754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14755
14756 AddSSLSocketData();
14757
14758 // Retry the second request on a second connection.
14759 SpdyTestUtil spdy_util2;
14760 SpdySerializedFrame req3(
14761 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14762 MockWrite writes2[] = {
14763 CreateMockWrite(req3, 0),
14764 };
14765
14766 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14767 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14768 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14769 MockRead(ASYNC, 0, 3)};
14770
14771 MockConnect connect2(ASYNC, OK, peer_addr);
14772 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14773 arraysize(writes2));
14774 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14775
14776 AddSSLSocketData();
14777
14778 // Preload mail.example.org into HostCache.
14779 HostPortPair host_port("mail.example.org", 443);
14780 HostResolver::RequestInfo resolve_info(host_port);
14781 AddressList ignored;
14782 std::unique_ptr<HostResolver::Request> request;
14783 TestCompletionCallback callback;
14784 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14785 &ignored, callback.callback(),
14786 &request, NetLogWithSource());
14787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14788 rv = callback.WaitForResult();
14789 EXPECT_THAT(rv, IsOk());
14790
14791 HttpRequestInfo request1;
14792 request1.method = "GET";
14793 request1.url = GURL("https://www.example.org/");
14794 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014795 request1.traffic_annotation =
14796 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914797 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14798
14799 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14801 rv = callback.WaitForResult();
14802 EXPECT_THAT(rv, IsOk());
14803
14804 const HttpResponseInfo* response = trans1.GetResponseInfo();
14805 ASSERT_TRUE(response);
14806 ASSERT_TRUE(response->headers);
14807 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14808 EXPECT_TRUE(response->was_fetched_via_spdy);
14809 EXPECT_TRUE(response->was_alpn_negotiated);
14810 std::string response_data;
14811 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14812 EXPECT_EQ("hello!", response_data);
14813
14814 HttpRequestInfo request2;
14815 request2.method = "GET";
14816 request2.url = GURL("https://mail.example.org/");
14817 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014818 request2.traffic_annotation =
14819 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914820 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14821
14822 BoundTestNetLog log;
14823 rv = trans2.Start(&request2, callback.callback(), log.bound());
14824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14825 rv = callback.WaitForResult();
14826 EXPECT_THAT(rv, IsOk());
14827
14828 response = trans2.GetResponseInfo();
14829 ASSERT_TRUE(response);
14830 ASSERT_TRUE(response->headers);
14831 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14832 EXPECT_TRUE(response->was_fetched_via_spdy);
14833 EXPECT_TRUE(response->was_alpn_negotiated);
14834 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14835 EXPECT_EQ("hello!", response_data);
14836
14837 TestNetLogEntry::List entries;
14838 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914839 ExpectLogContainsSomewhere(
14840 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914841 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914842}
14843
14844// Test that HTTP 421 responses are properly returned to the caller if received
14845// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14846// portions of the response.
14847TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14848 // Two hosts resolve to the same IP address.
14849 const std::string ip_addr = "1.2.3.4";
14850 IPAddress ip;
14851 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14852 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14853
Jeremy Roman0579ed62017-08-29 15:56:1914854 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914855 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14856 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14857
14858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14859
14860 // Two requests on the first connection.
14861 SpdySerializedFrame req1(
14862 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14863 spdy_util_.UpdateWithStreamDestruction(1);
14864 SpdySerializedFrame req2(
14865 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14866 SpdySerializedFrame rst(
14867 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14868 MockWrite writes1[] = {
14869 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14870 CreateMockWrite(rst, 6),
14871 };
14872
14873 // The first one succeeds, the second gets error 421 Misdirected Request.
14874 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14875 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14876 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714877 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914878 SpdySerializedFrame resp2(
14879 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14880 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14881 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14882
14883 MockConnect connect1(ASYNC, OK, peer_addr);
14884 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14885 arraysize(writes1));
14886 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14887
14888 AddSSLSocketData();
14889
14890 // Retry the second request on a second connection. It returns 421 Misdirected
14891 // Retry again.
14892 SpdyTestUtil spdy_util2;
14893 SpdySerializedFrame req3(
14894 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14895 MockWrite writes2[] = {
14896 CreateMockWrite(req3, 0),
14897 };
14898
14899 SpdySerializedFrame resp3(
14900 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14901 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14902 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14903 MockRead(ASYNC, 0, 3)};
14904
14905 MockConnect connect2(ASYNC, OK, peer_addr);
14906 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14907 arraysize(writes2));
14908 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14909
14910 AddSSLSocketData();
14911
14912 // Preload mail.example.org into HostCache.
14913 HostPortPair host_port("mail.example.org", 443);
14914 HostResolver::RequestInfo resolve_info(host_port);
14915 AddressList ignored;
14916 std::unique_ptr<HostResolver::Request> request;
14917 TestCompletionCallback callback;
14918 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14919 &ignored, callback.callback(),
14920 &request, NetLogWithSource());
14921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14922 rv = callback.WaitForResult();
14923 EXPECT_THAT(rv, IsOk());
14924
14925 HttpRequestInfo request1;
14926 request1.method = "GET";
14927 request1.url = GURL("https://www.example.org/");
14928 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014929 request1.traffic_annotation =
14930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914931 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14932
14933 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14935 rv = callback.WaitForResult();
14936 EXPECT_THAT(rv, IsOk());
14937
14938 const HttpResponseInfo* response = trans1.GetResponseInfo();
14939 ASSERT_TRUE(response);
14940 ASSERT_TRUE(response->headers);
14941 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14942 EXPECT_TRUE(response->was_fetched_via_spdy);
14943 EXPECT_TRUE(response->was_alpn_negotiated);
14944 std::string response_data;
14945 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14946 EXPECT_EQ("hello!", response_data);
14947
14948 HttpRequestInfo request2;
14949 request2.method = "GET";
14950 request2.url = GURL("https://mail.example.org/");
14951 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014952 request2.traffic_annotation =
14953 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914954 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14955
14956 BoundTestNetLog log;
14957 rv = trans2.Start(&request2, callback.callback(), log.bound());
14958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14959 rv = callback.WaitForResult();
14960 EXPECT_THAT(rv, IsOk());
14961
14962 // After a retry, the 421 Misdirected Request is reported back up to the
14963 // caller.
14964 response = trans2.GetResponseInfo();
14965 ASSERT_TRUE(response);
14966 ASSERT_TRUE(response->headers);
14967 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14968 EXPECT_TRUE(response->was_fetched_via_spdy);
14969 EXPECT_TRUE(response->was_alpn_negotiated);
14970 EXPECT_TRUE(response->ssl_info.cert);
14971 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14972 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914973}
14974
bnc6dcd8192017-05-25 20:11:5014975class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614976 public:
14977 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014978 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714979 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614980
dchengb03027d2014-10-21 12:00:2014981 int ResolveFromCache(const RequestInfo& info,
14982 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014983 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014984 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014985 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014986 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614987 return rv;
14988 }
14989
[email protected]e3ceb682011-06-28 23:55:4614990 private:
[email protected]e3ceb682011-06-28 23:55:4614991 const HostPortPair host_port_;
14992};
14993
bncd16676a2016-07-20 16:23:0114994TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314995 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614996 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914997 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714998 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615000
bnc032658ba2016-09-26 18:17:1515001 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615002
bncdf80d44fd2016-07-15 20:27:4115003 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915004 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815005 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4115006 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715007 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615008 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115009 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615010 };
bnc42331402016-07-25 13:36:1515011 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115012 SpdySerializedFrame host1_resp_body(
15013 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1515014 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115015 SpdySerializedFrame host2_resp_body(
15016 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615017 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115018 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15019 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315020 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615021 };
15022
eroman36d84e54432016-03-17 03:23:0215023 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215024 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1315025 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
15026 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0715027 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615028
[email protected]aa22b242011-11-16 18:58:2915029 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615030 HttpRequestInfo request1;
15031 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315032 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615033 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015034 request1.traffic_annotation =
15035 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015036 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615037
tfarina42834112016-09-22 13:38:2015038 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15040 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615041
15042 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215043 ASSERT_TRUE(response);
15044 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215045 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615046
15047 std::string response_data;
robpercival214763f2016-07-01 23:27:0115048 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615049 EXPECT_EQ("hello!", response_data);
15050
15051 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715052 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615053 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015054 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015055 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15056 &ignored, callback.callback(),
15057 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715059 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115060 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615061
15062 HttpRequestInfo request2;
15063 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715064 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615065 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015066 request2.traffic_annotation =
15067 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015068 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615069
tfarina42834112016-09-22 13:38:2015070 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15072 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615073
15074 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215075 ASSERT_TRUE(response);
15076 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215077 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615078 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215079 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115080 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615081 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615082}
15083
bncd16676a2016-07-20 16:23:0115084TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315085 const std::string https_url = "https://www.example.org:8080/";
15086 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415087
15088 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115089 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915090 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415091
15092 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115093 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415094 };
15095
bnc42331402016-07-25 13:36:1515096 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115097 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15098 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915099 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415100
rch8e6c6c42015-05-01 14:05:1315101 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15102 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415103 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715104 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415105
15106 // HTTP GET for the HTTP URL
15107 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315108 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415109 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315110 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415111 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415112 };
15113
15114 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315115 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15116 MockRead(ASYNC, 2, "hello"),
15117 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415118 };
15119
rch8e6c6c42015-05-01 14:05:1315120 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15121 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0415122
[email protected]8450d722012-07-02 19:14:0415123 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615124 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715125 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15126 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15127 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415128
danakj1fd259a02016-04-16 03:17:0915129 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415130
15131 // Start the first transaction to set up the SpdySession
15132 HttpRequestInfo request1;
15133 request1.method = "GET";
15134 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415135 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015136 request1.traffic_annotation =
15137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015138 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415139 TestCompletionCallback callback1;
15140 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015141 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515142 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415143
robpercival214763f2016-07-01 23:27:0115144 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415145 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15146
15147 // Now, start the HTTP request
15148 HttpRequestInfo request2;
15149 request2.method = "GET";
15150 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415151 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015152 request2.traffic_annotation =
15153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015154 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415155 TestCompletionCallback callback2;
15156 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015157 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515158 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415159
robpercival214763f2016-07-01 23:27:0115160 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415161 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15162}
15163
bnc5452e2a2015-05-08 16:27:4215164// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15165// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115166TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515167 url::SchemeHostPort server("https", "www.example.org", 443);
15168 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215169
bnc8bef8da22016-05-30 01:28:2515170 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215171 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615172 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215173 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15174
15175 // No data should be read from the alternative, because HTTP/1.1 is
15176 // negotiated.
15177 StaticSocketDataProvider data;
15178 session_deps_.socket_factory->AddSocketDataProvider(&data);
15179
15180 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615181 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215182 // mocked. This way the request relies on the alternate Job.
15183 StaticSocketDataProvider data_refused;
15184 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15185 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15186
zhongyi3d4a55e72016-04-22 20:36:4615187 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015189 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215190 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115191 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215192 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115193 http_server_properties->SetHttp2AlternativeService(
15194 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215195
bnc5452e2a2015-05-08 16:27:4215196 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615197 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215198 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515199 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1015200 request.traffic_annotation =
15201 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215202 TestCompletionCallback callback;
15203
15204 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215205 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015206 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215207 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215208}
15209
bnc40448a532015-05-11 19:13:1415210// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615211// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415212// succeeds, the request should succeed, even if the latter fails because
15213// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115214TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515215 url::SchemeHostPort server("https", "www.example.org", 443);
15216 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415217
15218 // Negotiate HTTP/1.1 with alternative.
15219 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615220 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415221 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15222
15223 // No data should be read from the alternative, because HTTP/1.1 is
15224 // negotiated.
15225 StaticSocketDataProvider data;
15226 session_deps_.socket_factory->AddSocketDataProvider(&data);
15227
zhongyi3d4a55e72016-04-22 20:36:4615228 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415229 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615230 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415231 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15232
15233 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515234 MockWrite("GET / HTTP/1.1\r\n"
15235 "Host: www.example.org\r\n"
15236 "Connection: keep-alive\r\n\r\n"),
15237 MockWrite("GET /second HTTP/1.1\r\n"
15238 "Host: www.example.org\r\n"
15239 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415240 };
15241
15242 MockRead http_reads[] = {
15243 MockRead("HTTP/1.1 200 OK\r\n"),
15244 MockRead("Content-Type: text/html\r\n"),
15245 MockRead("Content-Length: 6\r\n\r\n"),
15246 MockRead("foobar"),
15247 MockRead("HTTP/1.1 200 OK\r\n"),
15248 MockRead("Content-Type: text/html\r\n"),
15249 MockRead("Content-Length: 7\r\n\r\n"),
15250 MockRead("another"),
15251 };
15252 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15253 http_writes, arraysize(http_writes));
15254 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15255
zhongyi3d4a55e72016-04-22 20:36:4615256 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015258 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415259 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115260 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215261 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115262 http_server_properties->SetHttp2AlternativeService(
15263 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415264
15265 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15266 HttpRequestInfo request1;
15267 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515268 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415269 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015270 request1.traffic_annotation =
15271 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415272 TestCompletionCallback callback1;
15273
tfarina42834112016-09-22 13:38:2015274 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415275 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115276 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415277
15278 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215279 ASSERT_TRUE(response1);
15280 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415281 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15282
15283 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115284 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415285 EXPECT_EQ("foobar", response_data1);
15286
15287 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15288 // for alternative service.
15289 EXPECT_TRUE(
15290 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15291
zhongyi3d4a55e72016-04-22 20:36:4615292 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415293 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615294 // to server.
bnc40448a532015-05-11 19:13:1415295 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15296 HttpRequestInfo request2;
15297 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515298 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415299 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015300 request2.traffic_annotation =
15301 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415302 TestCompletionCallback callback2;
15303
tfarina42834112016-09-22 13:38:2015304 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415305 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115306 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415307
15308 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215309 ASSERT_TRUE(response2);
15310 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415311 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15312
15313 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115314 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415315 EXPECT_EQ("another", response_data2);
15316}
15317
bnc5452e2a2015-05-08 16:27:4215318// Alternative service requires HTTP/2 (or SPDY), but there is already a
15319// HTTP/1.1 socket open to the alternative server. That socket should not be
15320// used.
bncd16676a2016-07-20 16:23:0115321TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615322 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215323 HostPortPair alternative("alternative.example.org", 443);
15324 std::string origin_url = "https://origin.example.org:443";
15325 std::string alternative_url = "https://alternative.example.org:443";
15326
15327 // Negotiate HTTP/1.1 with alternative.example.org.
15328 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615329 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15331
15332 // HTTP/1.1 data for |request1| and |request2|.
15333 MockWrite http_writes[] = {
15334 MockWrite(
15335 "GET / HTTP/1.1\r\n"
15336 "Host: alternative.example.org\r\n"
15337 "Connection: keep-alive\r\n\r\n"),
15338 MockWrite(
15339 "GET / HTTP/1.1\r\n"
15340 "Host: alternative.example.org\r\n"
15341 "Connection: keep-alive\r\n\r\n"),
15342 };
15343
15344 MockRead http_reads[] = {
15345 MockRead(
15346 "HTTP/1.1 200 OK\r\n"
15347 "Content-Type: text/html; charset=iso-8859-1\r\n"
15348 "Content-Length: 40\r\n\r\n"
15349 "first HTTP/1.1 response from alternative"),
15350 MockRead(
15351 "HTTP/1.1 200 OK\r\n"
15352 "Content-Type: text/html; charset=iso-8859-1\r\n"
15353 "Content-Length: 41\r\n\r\n"
15354 "second HTTP/1.1 response from alternative"),
15355 };
15356 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15357 http_writes, arraysize(http_writes));
15358 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15359
15360 // This test documents that an alternate Job should not pool to an already
15361 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615362 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215363 StaticSocketDataProvider data_refused;
15364 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15365 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15366
zhongyi3d4a55e72016-04-22 20:36:4615367 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015369 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215370 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115371 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215372 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115373 http_server_properties->SetHttp2AlternativeService(
15374 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215375
15376 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215377 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615378 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215379 request1.method = "GET";
15380 request1.url = GURL(alternative_url);
15381 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015382 request1.traffic_annotation =
15383 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215384 TestCompletionCallback callback1;
15385
tfarina42834112016-09-22 13:38:2015386 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115387 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615388 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215389 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215390 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215391 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215392 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215393 EXPECT_FALSE(response1->was_fetched_via_spdy);
15394 std::string response_data1;
bnc691fda62016-08-12 00:43:1615395 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215396 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15397
15398 // Request for origin.example.org, which has an alternative service. This
15399 // will start two Jobs: the alternative looks for connections to pool to,
15400 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615401 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215402 // this request fails.
bnc5452e2a2015-05-08 16:27:4215403 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615404 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215405 request2.method = "GET";
15406 request2.url = GURL(origin_url);
15407 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015408 request2.traffic_annotation =
15409 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215410 TestCompletionCallback callback2;
15411
tfarina42834112016-09-22 13:38:2015412 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115413 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215414
15415 // Another transaction to alternative. This is to test that the HTTP/1.1
15416 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215417 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615418 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215419 request3.method = "GET";
15420 request3.url = GURL(alternative_url);
15421 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015422 request3.traffic_annotation =
15423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215424 TestCompletionCallback callback3;
15425
tfarina42834112016-09-22 13:38:2015426 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115427 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615428 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215429 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215430 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215431 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215432 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215433 EXPECT_FALSE(response3->was_fetched_via_spdy);
15434 std::string response_data3;
bnc691fda62016-08-12 00:43:1615435 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215436 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15437}
15438
bncd16676a2016-07-20 16:23:0115439TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315440 const std::string https_url = "https://www.example.org:8080/";
15441 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415442
rdsmithebb50aa2015-11-12 03:44:3815443 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115444 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815445
[email protected]8450d722012-07-02 19:14:0415446 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315447 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115448 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415449 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115450 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915451 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115452 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215453 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915454
15455 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915456 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715457 req2_block[kHttp2MethodHeader] = "GET";
15458 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15459 req2_block[kHttp2SchemeHeader] = "http";
15460 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115461 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515462 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415463
15464 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115465 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15466 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415467 };
15468
bncdf80d44fd2016-07-15 20:27:4115469 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515470 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115471 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515472 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115473 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15474 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815475 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115476 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815477 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515478 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115479 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315480 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115481 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315482 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115483 CreateMockRead(wrapped_resp1, 4),
15484 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315485 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115486 CreateMockRead(resp2, 8),
15487 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315488 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15489 };
[email protected]8450d722012-07-02 19:14:0415490
mmenke666a6fea2015-12-19 04:16:3315491 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15492 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415493 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715494 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415495
Lily Houghton8c2f97d2018-01-22 05:06:5915496 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915497 ProxyResolutionService::CreateFixedFromPacResult(
15498 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115499 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715500 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415501 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615502 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415504 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615505 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15507 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415508
danakj1fd259a02016-04-16 03:17:0915509 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415510
15511 // Start the first transaction to set up the SpdySession
15512 HttpRequestInfo request1;
15513 request1.method = "GET";
15514 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415515 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015516 request1.traffic_annotation =
15517 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015518 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415519 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015520 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415521
mmenke666a6fea2015-12-19 04:16:3315522 // This pause is a hack to avoid running into https://crbug.com/497228.
15523 data1.RunUntilPaused();
15524 base::RunLoop().RunUntilIdle();
15525 data1.Resume();
robpercival214763f2016-07-01 23:27:0115526 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415527 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15528
[email protected]f6c63db52013-02-02 00:35:2215529 LoadTimingInfo load_timing_info1;
15530 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15531 TestLoadTimingNotReusedWithPac(load_timing_info1,
15532 CONNECT_TIMING_HAS_SSL_TIMES);
15533
mmenke666a6fea2015-12-19 04:16:3315534 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415535 HttpRequestInfo request2;
15536 request2.method = "GET";
15537 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415538 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015539 request2.traffic_annotation =
15540 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015541 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415542 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015543 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415544
mmenke666a6fea2015-12-19 04:16:3315545 // This pause is a hack to avoid running into https://crbug.com/497228.
15546 data1.RunUntilPaused();
15547 base::RunLoop().RunUntilIdle();
15548 data1.Resume();
robpercival214763f2016-07-01 23:27:0115549 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315550
[email protected]8450d722012-07-02 19:14:0415551 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215552
15553 LoadTimingInfo load_timing_info2;
15554 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15555 // The established SPDY sessions is considered reused by the HTTP request.
15556 TestLoadTimingReusedWithPac(load_timing_info2);
15557 // HTTP requests over a SPDY session should have a different connection
15558 // socket_log_id than requests over a tunnel.
15559 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415560}
15561
[email protected]2d88e7d2012-07-19 17:55:1715562// Test that in the case where we have a SPDY session to a SPDY proxy
15563// that we do not pool other origins that resolve to the same IP when
15564// the certificate does not match the new origin.
15565// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115566TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315567 const std::string url1 = "http://www.example.org/";
15568 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715569 const std::string ip_addr = "1.2.3.4";
15570
rdsmithebb50aa2015-11-12 03:44:3815571 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115572 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815573
[email protected]2d88e7d2012-07-19 17:55:1715574 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615575 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315576 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115577 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515578 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715579
15580 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115581 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715582 };
15583
bnc42331402016-07-25 13:36:1515584 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115585 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715586 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115587 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15588 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715589 };
15590
mmenke666a6fea2015-12-19 04:16:3315591 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15592 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215593 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915594 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715595 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15596 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315597 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715598
15599 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115600 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915601 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715602
15603 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115604 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715605 };
15606
bnc42331402016-07-25 13:36:1515607 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115608 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15609 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315610 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715611
mmenke666a6fea2015-12-19 04:16:3315612 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15613 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715614 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315615 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715616
15617 // Set up a proxy config that sends HTTP requests to a proxy, and
15618 // all others direct.
15619 ProxyConfig proxy_config;
15620 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915621 session_deps_.proxy_resolution_service =
15622 std::make_unique<ProxyResolutionService>(
15623 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15624 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15625 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715626
bncce36dca22015-04-21 22:11:2315627 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615628 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715629 // Load a valid cert. Note, that this does not need to
15630 // be valid for proxy because the MockSSLClientSocket does
15631 // not actually verify it. But SpdySession will use this
15632 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915633 ssl1.ssl_info.cert =
15634 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15635 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315636 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15637 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715638
15639 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615640 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315641 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15642 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715643
Jeremy Roman0579ed62017-08-29 15:56:1915644 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315645 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715646 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715647
danakj1fd259a02016-04-16 03:17:0915648 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715649
15650 // Start the first transaction to set up the SpdySession
15651 HttpRequestInfo request1;
15652 request1.method = "GET";
15653 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715654 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015655 request1.traffic_annotation =
15656 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015657 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715658 TestCompletionCallback callback1;
15659 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015660 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315661 // This pause is a hack to avoid running into https://crbug.com/497228.
15662 data1.RunUntilPaused();
15663 base::RunLoop().RunUntilIdle();
15664 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715665
robpercival214763f2016-07-01 23:27:0115666 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715667 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15668
15669 // Now, start the HTTP request
15670 HttpRequestInfo request2;
15671 request2.method = "GET";
15672 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715673 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015674 request2.traffic_annotation =
15675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015676 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715677 TestCompletionCallback callback2;
15678 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015679 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515680 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715681
15682 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115683 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715684 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15685}
15686
[email protected]85f97342013-04-17 06:12:2415687// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15688// error) in SPDY session, removes the socket from pool and closes the SPDY
15689// session. Verify that new url's from the same HttpNetworkSession (and a new
15690// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115691TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315692 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415693
15694 MockRead reads1[] = {
15695 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15696 };
15697
mmenke11eb5152015-06-09 14:50:5015698 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415699
bncdf80d44fd2016-07-15 20:27:4115700 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915701 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415702 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115703 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415704 };
15705
bnc42331402016-07-25 13:36:1515706 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115707 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415708 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115709 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15710 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415711 };
15712
mmenke11eb5152015-06-09 14:50:5015713 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15714 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415715
[email protected]85f97342013-04-17 06:12:2415716 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615717 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15719 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415720
15721 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615722 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15724 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415725
danakj1fd259a02016-04-16 03:17:0915726 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015727 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415728
15729 // Start the first transaction to set up the SpdySession and verify that
15730 // connection was closed.
15731 HttpRequestInfo request1;
15732 request1.method = "GET";
15733 request1.url = GURL(https_url);
15734 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015735 request1.traffic_annotation =
15736 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015737 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415738 TestCompletionCallback callback1;
15739 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015740 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115741 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415742
15743 // Now, start the second request and make sure it succeeds.
15744 HttpRequestInfo request2;
15745 request2.method = "GET";
15746 request2.url = GURL(https_url);
15747 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015748 request2.traffic_annotation =
15749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015750 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415751 TestCompletionCallback callback2;
15752 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015753 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415754
robpercival214763f2016-07-01 23:27:0115755 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415756 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15757}
15758
bncd16676a2016-07-20 16:23:0115759TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315760 ClientSocketPoolManager::set_max_sockets_per_group(
15761 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15762 ClientSocketPoolManager::set_max_sockets_per_pool(
15763 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15764
15765 // Use two different hosts with different IPs so they don't get pooled.
15766 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15767 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315769
15770 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615771 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315772 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615773 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15776
bncdf80d44fd2016-07-15 20:27:4115777 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915778 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315779 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115780 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315781 };
bnc42331402016-07-25 13:36:1515782 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115783 SpdySerializedFrame host1_resp_body(
15784 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315785 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115786 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915787 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315788 };
15789
rdsmithebb50aa2015-11-12 03:44:3815790 // Use a separate test instance for the separate SpdySession that will be
15791 // created.
bncd16676a2016-07-20 16:23:0115792 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915793 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815794 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15795 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315796 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15797
bncdf80d44fd2016-07-15 20:27:4115798 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915799 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315800 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115801 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315802 };
bnc42331402016-07-25 13:36:1515803 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115804 SpdySerializedFrame host2_resp_body(
15805 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315806 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115807 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915808 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315809 };
15810
Jeremy Roman0579ed62017-08-29 15:56:1915811 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815812 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15813 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315814 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15815
15816 MockWrite http_write[] = {
15817 MockWrite("GET / HTTP/1.1\r\n"
15818 "Host: www.a.com\r\n"
15819 "Connection: keep-alive\r\n\r\n"),
15820 };
15821
15822 MockRead http_read[] = {
15823 MockRead("HTTP/1.1 200 OK\r\n"),
15824 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15825 MockRead("Content-Length: 6\r\n\r\n"),
15826 MockRead("hello!"),
15827 };
15828 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15829 http_write, arraysize(http_write));
15830 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15831
15832 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415833 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15834 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315835 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615836 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315837
15838 TestCompletionCallback callback;
15839 HttpRequestInfo request1;
15840 request1.method = "GET";
15841 request1.url = GURL("https://www.a.com/");
15842 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015843 request1.traffic_annotation =
15844 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815845 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915846 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315847
tfarina42834112016-09-22 13:38:2015848 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115849 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15850 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315851
15852 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215853 ASSERT_TRUE(response);
15854 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215855 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315856 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215857 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315858
15859 std::string response_data;
robpercival214763f2016-07-01 23:27:0115860 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315861 EXPECT_EQ("hello!", response_data);
15862 trans.reset();
15863 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615864 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315865
15866 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415867 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15868 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315869 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615870 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315871 HttpRequestInfo request2;
15872 request2.method = "GET";
15873 request2.url = GURL("https://www.b.com/");
15874 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015875 request2.traffic_annotation =
15876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815877 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315879
tfarina42834112016-09-22 13:38:2015880 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15882 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315883
15884 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215885 ASSERT_TRUE(response);
15886 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215887 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315888 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215889 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115890 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315891 EXPECT_EQ("hello!", response_data);
15892 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615893 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315894 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615895 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315896
15897 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415898 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15899 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315900 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615901 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315902 HttpRequestInfo request3;
15903 request3.method = "GET";
15904 request3.url = GURL("http://www.a.com/");
15905 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015906 request3.traffic_annotation =
15907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815908 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915909 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315910
tfarina42834112016-09-22 13:38:2015911 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15913 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315914
15915 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215916 ASSERT_TRUE(response);
15917 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315918 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15919 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215920 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115921 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315922 EXPECT_EQ("hello!", response_data);
15923 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615924 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315925 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615926 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315927}
15928
bncd16676a2016-07-20 16:23:0115929TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415930 HttpRequestInfo request;
15931 request.method = "GET";
bncce36dca22015-04-21 22:11:2315932 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015933 request.traffic_annotation =
15934 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415935
danakj1fd259a02016-04-16 03:17:0915936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415938
ttuttled9dbc652015-09-29 20:00:5915939 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415940 StaticSocketDataProvider data;
15941 data.set_connect_data(mock_connect);
15942 session_deps_.socket_factory->AddSocketDataProvider(&data);
15943
15944 TestCompletionCallback callback;
15945
tfarina42834112016-09-22 13:38:2015946 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115947 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415948
15949 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115950 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415951
[email protected]79e1fd62013-06-20 06:50:0415952 // We don't care whether this succeeds or fails, but it shouldn't crash.
15953 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615954 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715955
15956 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615957 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715958 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115959 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915960
15961 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615962 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915963 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415964}
15965
bncd16676a2016-07-20 16:23:0115966TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415967 HttpRequestInfo request;
15968 request.method = "GET";
bncce36dca22015-04-21 22:11:2315969 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015970 request.traffic_annotation =
15971 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415972
danakj1fd259a02016-04-16 03:17:0915973 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615974 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415975
ttuttled9dbc652015-09-29 20:00:5915976 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415977 StaticSocketDataProvider data;
15978 data.set_connect_data(mock_connect);
15979 session_deps_.socket_factory->AddSocketDataProvider(&data);
15980
15981 TestCompletionCallback callback;
15982
tfarina42834112016-09-22 13:38:2015983 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415985
15986 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115987 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415988
[email protected]79e1fd62013-06-20 06:50:0415989 // We don't care whether this succeeds or fails, but it shouldn't crash.
15990 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615991 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715992
15993 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615994 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715995 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115996 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915997
15998 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615999 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916000 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416001}
16002
bncd16676a2016-07-20 16:23:0116003TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416004 HttpRequestInfo request;
16005 request.method = "GET";
bncce36dca22015-04-21 22:11:2316006 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016007 request.traffic_annotation =
16008 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416009
danakj1fd259a02016-04-16 03:17:0916010 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416012
16013 MockWrite data_writes[] = {
16014 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16015 };
16016 MockRead data_reads[] = {
16017 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16018 };
16019
16020 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16021 data_writes, arraysize(data_writes));
16022 session_deps_.socket_factory->AddSocketDataProvider(&data);
16023
16024 TestCompletionCallback callback;
16025
tfarina42834112016-09-22 13:38:2016026 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416028
16029 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116030 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416031
[email protected]79e1fd62013-06-20 06:50:0416032 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616033 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416034 EXPECT_TRUE(request_headers.HasHeader("Host"));
16035}
16036
bncd16676a2016-07-20 16:23:0116037TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416038 HttpRequestInfo request;
16039 request.method = "GET";
bncce36dca22015-04-21 22:11:2316040 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016041 request.traffic_annotation =
16042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416043
danakj1fd259a02016-04-16 03:17:0916044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416046
16047 MockWrite data_writes[] = {
16048 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16049 };
16050 MockRead data_reads[] = {
16051 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16052 };
16053
16054 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16055 data_writes, arraysize(data_writes));
16056 session_deps_.socket_factory->AddSocketDataProvider(&data);
16057
16058 TestCompletionCallback callback;
16059
tfarina42834112016-09-22 13:38:2016060 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416062
16063 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116064 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416065
[email protected]79e1fd62013-06-20 06:50:0416066 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616067 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416068 EXPECT_TRUE(request_headers.HasHeader("Host"));
16069}
16070
bncd16676a2016-07-20 16:23:0116071TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416072 HttpRequestInfo request;
16073 request.method = "GET";
bncce36dca22015-04-21 22:11:2316074 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016075 request.traffic_annotation =
16076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416077
danakj1fd259a02016-04-16 03:17:0916078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416080
16081 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316082 MockWrite(
16083 "GET / HTTP/1.1\r\n"
16084 "Host: www.example.org\r\n"
16085 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416086 };
16087 MockRead data_reads[] = {
16088 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16089 };
16090
16091 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16092 data_writes, arraysize(data_writes));
16093 session_deps_.socket_factory->AddSocketDataProvider(&data);
16094
16095 TestCompletionCallback callback;
16096
tfarina42834112016-09-22 13:38:2016097 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416099
16100 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116101 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416102
[email protected]79e1fd62013-06-20 06:50:0416103 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616104 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416105 EXPECT_TRUE(request_headers.HasHeader("Host"));
16106}
16107
bncd16676a2016-07-20 16:23:0116108TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416109 HttpRequestInfo request;
16110 request.method = "GET";
bncce36dca22015-04-21 22:11:2316111 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016112 request.traffic_annotation =
16113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416114
danakj1fd259a02016-04-16 03:17:0916115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416117
16118 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316119 MockWrite(
16120 "GET / HTTP/1.1\r\n"
16121 "Host: www.example.org\r\n"
16122 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416123 };
16124 MockRead data_reads[] = {
16125 MockRead(ASYNC, ERR_CONNECTION_RESET),
16126 };
16127
16128 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16129 data_writes, arraysize(data_writes));
16130 session_deps_.socket_factory->AddSocketDataProvider(&data);
16131
16132 TestCompletionCallback callback;
16133
tfarina42834112016-09-22 13:38:2016134 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116135 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416136
16137 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116138 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416139
[email protected]79e1fd62013-06-20 06:50:0416140 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616141 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416142 EXPECT_TRUE(request_headers.HasHeader("Host"));
16143}
16144
bncd16676a2016-07-20 16:23:0116145TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416146 HttpRequestInfo request;
16147 request.method = "GET";
bncce36dca22015-04-21 22:11:2316148 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416149 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016150 request.traffic_annotation =
16151 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416152
danakj1fd259a02016-04-16 03:17:0916153 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616154 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416155
16156 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316157 MockWrite(
16158 "GET / HTTP/1.1\r\n"
16159 "Host: www.example.org\r\n"
16160 "Connection: keep-alive\r\n"
16161 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416162 };
16163 MockRead data_reads[] = {
16164 MockRead("HTTP/1.1 200 OK\r\n"
16165 "Content-Length: 5\r\n\r\n"
16166 "hello"),
16167 MockRead(ASYNC, ERR_UNEXPECTED),
16168 };
16169
16170 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16171 data_writes, arraysize(data_writes));
16172 session_deps_.socket_factory->AddSocketDataProvider(&data);
16173
16174 TestCompletionCallback callback;
16175
tfarina42834112016-09-22 13:38:2016176 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416178
16179 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116180 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416181
16182 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616183 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416184 std::string foo;
16185 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16186 EXPECT_EQ("bar", foo);
16187}
16188
[email protected]bf828982013-08-14 18:01:4716189namespace {
16190
yhiranoa7e05bb2014-11-06 05:40:3916191// Fake HttpStream that simply records calls to SetPriority().
16192class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0316193 public base::SupportsWeakPtr<FakeStream> {
16194 public:
16195 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2716196 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0316197
16198 RequestPriority priority() const { return priority_; }
16199
dchengb03027d2014-10-21 12:00:2016200 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716201 bool can_send_early,
dchengb03027d2014-10-21 12:00:2016202 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016203 const NetLogWithSource& net_log,
Bence Békya25e3f72018-02-13 21:13:3916204 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316205 return ERR_IO_PENDING;
16206 }
16207
dchengb03027d2014-10-21 12:00:2016208 int SendRequest(const HttpRequestHeaders& request_headers,
16209 HttpResponseInfo* response,
Bence Békya25e3f72018-02-13 21:13:3916210 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316211 ADD_FAILURE();
16212 return ERR_UNEXPECTED;
16213 }
16214
Bence Békya25e3f72018-02-13 21:13:3916215 int ReadResponseHeaders(CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316216 ADD_FAILURE();
16217 return ERR_UNEXPECTED;
16218 }
16219
dchengb03027d2014-10-21 12:00:2016220 int ReadResponseBody(IOBuffer* buf,
16221 int buf_len,
Bence Békya25e3f72018-02-13 21:13:3916222 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316223 ADD_FAILURE();
16224 return ERR_UNEXPECTED;
16225 }
16226
dchengb03027d2014-10-21 12:00:2016227 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0316228
dchengb03027d2014-10-21 12:00:2016229 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0316230 ADD_FAILURE();
16231 return false;
16232 }
16233
dchengb03027d2014-10-21 12:00:2016234 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0316235 ADD_FAILURE();
16236 return false;
16237 }
16238
dchengb03027d2014-10-21 12:00:2016239 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316240
mmenkebd84c392015-09-02 14:12:3416241 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0316242
sclittle4de1bab92015-09-22 21:28:2416243 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5916244 ADD_FAILURE();
16245 return 0;
16246 }
16247
sclittlebe1ccf62015-09-02 19:40:3616248 int64_t GetTotalSentBytes() const override {
16249 ADD_FAILURE();
16250 return 0;
16251 }
16252
dchengb03027d2014-10-21 12:00:2016253 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0316254 ADD_FAILURE();
16255 return false;
16256 }
16257
rchcd379012017-04-12 21:53:3216258 bool GetAlternativeService(
16259 AlternativeService* alternative_service) const override {
16260 ADD_FAILURE();
16261 return false;
16262 }
16263
dchengb03027d2014-10-21 12:00:2016264 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
16265
16266 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0316267 ADD_FAILURE();
16268 }
16269
ttuttled9dbc652015-09-29 20:00:5916270 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16271
nharper78e6d2b2016-09-21 05:42:3516272 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16273 TokenBindingType tb_type,
16274 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416275 ADD_FAILURE();
16276 return ERR_NOT_IMPLEMENTED;
16277 }
16278
dchengb03027d2014-10-21 12:00:2016279 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316280
zhongyica364fbb2015-12-12 03:39:1216281 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16282
dchengb03027d2014-10-21 12:00:2016283 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0316284
yhiranoa7e05bb2014-11-06 05:40:3916285 HttpStream* RenewStreamForAuth() override { return NULL; }
16286
Andrey Kosyakov83a6eee2017-08-14 19:20:0416287 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
16288
[email protected]e86839fd2013-08-14 18:29:0316289 private:
16290 RequestPriority priority_;
16291
16292 DISALLOW_COPY_AND_ASSIGN(FakeStream);
16293};
16294
16295// Fake HttpStreamRequest that simply records calls to SetPriority()
16296// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4716297class FakeStreamRequest : public HttpStreamRequest,
16298 public base::SupportsWeakPtr<FakeStreamRequest> {
16299 public:
[email protected]e86839fd2013-08-14 18:29:0316300 FakeStreamRequest(RequestPriority priority,
16301 HttpStreamRequest::Delegate* delegate)
16302 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4416303 delegate_(delegate),
16304 websocket_stream_create_helper_(NULL) {}
16305
16306 FakeStreamRequest(RequestPriority priority,
16307 HttpStreamRequest::Delegate* delegate,
16308 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
16309 : priority_(priority),
16310 delegate_(delegate),
16311 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0316312
Chris Watkins7a41d3552017-12-01 02:13:2716313 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4716314
16315 RequestPriority priority() const { return priority_; }
16316
[email protected]831e4a32013-11-14 02:14:4416317 const WebSocketHandshakeStreamBase::CreateHelper*
16318 websocket_stream_create_helper() const {
16319 return websocket_stream_create_helper_;
16320 }
16321
[email protected]e86839fd2013-08-14 18:29:0316322 // Create a new FakeStream and pass it to the request's
16323 // delegate. Returns a weak pointer to the FakeStream.
16324 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1916325 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0316326 // Do this before calling OnStreamReady() as OnStreamReady() may
16327 // immediately delete |fake_stream|.
16328 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0016329 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0316330 return weak_stream;
16331 }
16332
asanka681f02d2017-02-22 17:06:3916333 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4716334 ADD_FAILURE();
16335 return ERR_UNEXPECTED;
16336 }
16337
dchengb03027d2014-10-21 12:00:2016338 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4716339 ADD_FAILURE();
16340 return LoadState();
16341 }
16342
dchengb03027d2014-10-21 12:00:2016343 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4716344
bnc94c92842016-09-21 15:22:5216345 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716346
bnc6227b26e2016-08-12 02:00:4316347 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4716348
dchengb03027d2014-10-21 12:00:2016349 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716350
ttuttle1f2d7e92015-04-28 16:17:4716351 const ConnectionAttempts& connection_attempts() const override {
16352 static ConnectionAttempts no_attempts;
16353 return no_attempts;
16354 }
16355
[email protected]bf828982013-08-14 18:01:4716356 private:
16357 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0316358 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4416359 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4716360
16361 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
16362};
16363
16364// Fake HttpStreamFactory that vends FakeStreamRequests.
16365class FakeStreamFactory : public HttpStreamFactory {
16366 public:
Chris Watkins7a41d3552017-12-01 02:13:2716367 FakeStreamFactory() = default;
16368 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4716369
16370 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
16371 // RequestStream() (which may be NULL if it was destroyed already).
16372 base::WeakPtr<FakeStreamRequest> last_stream_request() {
16373 return last_stream_request_;
16374 }
16375
xunjieli96f2a402017-06-05 17:24:2716376 std::unique_ptr<HttpStreamRequest> RequestStream(
16377 const HttpRequestInfo& info,
16378 RequestPriority priority,
16379 const SSLConfig& server_ssl_config,
16380 const SSLConfig& proxy_ssl_config,
16381 HttpStreamRequest::Delegate* delegate,
16382 bool enable_ip_based_pooling,
16383 bool enable_alternative_services,
16384 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1916385 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4716386 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716387 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716388 }
16389
xunjieli96f2a402017-06-05 17:24:2716390 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0816391 const HttpRequestInfo& info,
16392 RequestPriority priority,
16393 const SSLConfig& server_ssl_config,
16394 const SSLConfig& proxy_ssl_config,
16395 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2916396 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616397 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016398 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0816399 NOTREACHED();
16400 return nullptr;
16401 }
16402
xunjieli96f2a402017-06-05 17:24:2716403 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4716404 const HttpRequestInfo& info,
16405 RequestPriority priority,
16406 const SSLConfig& server_ssl_config,
16407 const SSLConfig& proxy_ssl_config,
16408 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4616409 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2916410 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616411 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016412 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2716413 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1916414 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4416415 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716416 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716417 }
16418
dchengb03027d2014-10-21 12:00:2016419 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5916420 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4716421 ADD_FAILURE();
16422 }
16423
dchengb03027d2014-10-21 12:00:2016424 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4716425 ADD_FAILURE();
16426 return NULL;
16427 }
16428
xunjielif5267de2017-01-20 21:18:5716429 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
16430 const std::string& parent_absolute_name) const override {
16431 ADD_FAILURE();
16432 }
16433
[email protected]bf828982013-08-14 18:01:4716434 private:
16435 base::WeakPtr<FakeStreamRequest> last_stream_request_;
16436
16437 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16438};
16439
[email protected]bf828982013-08-14 18:01:4716440} // namespace
16441
16442// Make sure that HttpNetworkTransaction passes on its priority to its
16443// stream request on start.
bncd16676a2016-07-20 16:23:0116444TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916445 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216446 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716447 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916448 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716449
krasinc06a72a2016-12-21 03:42:4616450 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116451 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716452
Ramin Halavatib5e433e62018-02-07 07:41:1016453 request.traffic_annotation =
16454 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16455
wezca1070932016-05-26 20:30:5216456 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716457
[email protected]bf828982013-08-14 18:01:4716458 TestCompletionCallback callback;
16459 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016460 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716461
16462 base::WeakPtr<FakeStreamRequest> fake_request =
16463 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216464 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716465 EXPECT_EQ(LOW, fake_request->priority());
16466}
16467
16468// Make sure that HttpNetworkTransaction passes on its priority
16469// updates to its stream request.
bncd16676a2016-07-20 16:23:0116470TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216472 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716473 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916474 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716475
krasinc06a72a2016-12-21 03:42:4616476 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116477 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716478
Ramin Halavatib5e433e62018-02-07 07:41:1016479 request.traffic_annotation =
16480 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16481
[email protected]bf828982013-08-14 18:01:4716482 TestCompletionCallback callback;
16483 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016484 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716485
16486 base::WeakPtr<FakeStreamRequest> fake_request =
16487 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216488 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716489 EXPECT_EQ(LOW, fake_request->priority());
16490
16491 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216492 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716493 EXPECT_EQ(LOWEST, fake_request->priority());
16494}
16495
[email protected]e86839fd2013-08-14 18:29:0316496// Make sure that HttpNetworkTransaction passes on its priority
16497// updates to its stream.
bncd16676a2016-07-20 16:23:0116498TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216500 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316501 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916502 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316503
krasinc06a72a2016-12-21 03:42:4616504 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116505 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316506
Ramin Halavatib5e433e62018-02-07 07:41:1016507 request.traffic_annotation =
16508 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16509
[email protected]e86839fd2013-08-14 18:29:0316510 TestCompletionCallback callback;
16511 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016512 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316513
16514 base::WeakPtr<FakeStreamRequest> fake_request =
16515 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216516 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316517 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216518 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316519 EXPECT_EQ(LOW, fake_stream->priority());
16520
16521 trans.SetPriority(LOWEST);
16522 EXPECT_EQ(LOWEST, fake_stream->priority());
16523}
16524
[email protected]043b68c82013-08-22 23:41:5216525// Tests that when a used socket is returned to the SSL socket pool, it's closed
16526// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116527TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216528 ClientSocketPoolManager::set_max_sockets_per_group(
16529 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16530 ClientSocketPoolManager::set_max_sockets_per_pool(
16531 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16532
16533 // Set up SSL request.
16534
16535 HttpRequestInfo ssl_request;
16536 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316537 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016538 ssl_request.traffic_annotation =
16539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216540
16541 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316542 MockWrite(
16543 "GET / HTTP/1.1\r\n"
16544 "Host: www.example.org\r\n"
16545 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216546 };
16547 MockRead ssl_reads[] = {
16548 MockRead("HTTP/1.1 200 OK\r\n"),
16549 MockRead("Content-Length: 11\r\n\r\n"),
16550 MockRead("hello world"),
16551 MockRead(SYNCHRONOUS, OK),
16552 };
16553 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16554 ssl_writes, arraysize(ssl_writes));
16555 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16556
16557 SSLSocketDataProvider ssl(ASYNC, OK);
16558 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16559
16560 // Set up HTTP request.
16561
16562 HttpRequestInfo http_request;
16563 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316564 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016565 http_request.traffic_annotation =
16566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216567
16568 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316569 MockWrite(
16570 "GET / HTTP/1.1\r\n"
16571 "Host: www.example.org\r\n"
16572 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216573 };
16574 MockRead http_reads[] = {
16575 MockRead("HTTP/1.1 200 OK\r\n"),
16576 MockRead("Content-Length: 7\r\n\r\n"),
16577 MockRead("falafel"),
16578 MockRead(SYNCHRONOUS, OK),
16579 };
16580 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16581 http_writes, arraysize(http_writes));
16582 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16583
danakj1fd259a02016-04-16 03:17:0916584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216585
16586 // Start the SSL request.
16587 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616588 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016589 ASSERT_EQ(ERR_IO_PENDING,
16590 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16591 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216592
16593 // Start the HTTP request. Pool should stall.
16594 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616595 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016596 ASSERT_EQ(ERR_IO_PENDING,
16597 http_trans.Start(&http_request, http_callback.callback(),
16598 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116599 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216600
16601 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116602 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216603 std::string response_data;
bnc691fda62016-08-12 00:43:1616604 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216605 EXPECT_EQ("hello world", response_data);
16606
16607 // The SSL socket should automatically be closed, so the HTTP request can
16608 // start.
dcheng48459ac22014-08-26 00:46:4116609 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16610 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216611
16612 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116613 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616614 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216615 EXPECT_EQ("falafel", response_data);
16616
dcheng48459ac22014-08-26 00:46:4116617 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216618}
16619
16620// Tests that when a SSL connection is established but there's no corresponding
16621// request that needs it, the new socket is closed if the transport socket pool
16622// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116623TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216624 ClientSocketPoolManager::set_max_sockets_per_group(
16625 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16626 ClientSocketPoolManager::set_max_sockets_per_pool(
16627 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16628
16629 // Set up an ssl request.
16630
16631 HttpRequestInfo ssl_request;
16632 ssl_request.method = "GET";
16633 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1016634 ssl_request.traffic_annotation =
16635 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216636
16637 // No data will be sent on the SSL socket.
16638 StaticSocketDataProvider ssl_data;
16639 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16640
16641 SSLSocketDataProvider ssl(ASYNC, OK);
16642 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16643
16644 // Set up HTTP request.
16645
16646 HttpRequestInfo http_request;
16647 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316648 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016649 http_request.traffic_annotation =
16650 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216651
16652 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316653 MockWrite(
16654 "GET / HTTP/1.1\r\n"
16655 "Host: www.example.org\r\n"
16656 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216657 };
16658 MockRead http_reads[] = {
16659 MockRead("HTTP/1.1 200 OK\r\n"),
16660 MockRead("Content-Length: 7\r\n\r\n"),
16661 MockRead("falafel"),
16662 MockRead(SYNCHRONOUS, OK),
16663 };
16664 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16665 http_writes, arraysize(http_writes));
16666 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16667
danakj1fd259a02016-04-16 03:17:0916668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216669
16670 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16671 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916672 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916673 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116674 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216675
16676 // Start the HTTP request. Pool should stall.
16677 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616678 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016679 ASSERT_EQ(ERR_IO_PENDING,
16680 http_trans.Start(&http_request, http_callback.callback(),
16681 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116682 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216683
16684 // The SSL connection will automatically be closed once the connection is
16685 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116686 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216687 std::string response_data;
bnc691fda62016-08-12 00:43:1616688 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216689 EXPECT_EQ("falafel", response_data);
16690
dcheng48459ac22014-08-26 00:46:4116691 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216692}
16693
bncd16676a2016-07-20 16:23:0116694TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916695 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216696 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916697 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216698 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416699
16700 HttpRequestInfo request;
16701 request.method = "POST";
16702 request.url = GURL("http://www.foo.com/");
16703 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016704 request.traffic_annotation =
16705 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416706
danakj1fd259a02016-04-16 03:17:0916707 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416709 // Send headers successfully, but get an error while sending the body.
16710 MockWrite data_writes[] = {
16711 MockWrite("POST / HTTP/1.1\r\n"
16712 "Host: www.foo.com\r\n"
16713 "Connection: keep-alive\r\n"
16714 "Content-Length: 3\r\n\r\n"),
16715 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16716 };
16717
16718 MockRead data_reads[] = {
16719 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16720 MockRead("hello world"),
16721 MockRead(SYNCHRONOUS, OK),
16722 };
16723 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16724 arraysize(data_writes));
16725 session_deps_.socket_factory->AddSocketDataProvider(&data);
16726
16727 TestCompletionCallback callback;
16728
tfarina42834112016-09-22 13:38:2016729 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416731
16732 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116733 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416734
bnc691fda62016-08-12 00:43:1616735 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216736 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416737
wezca1070932016-05-26 20:30:5216738 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416739 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16740
16741 std::string response_data;
bnc691fda62016-08-12 00:43:1616742 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116743 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416744 EXPECT_EQ("hello world", response_data);
16745}
16746
16747// This test makes sure the retry logic doesn't trigger when reading an error
16748// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116749TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416750 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416752 MockWrite data_writes[] = {
16753 MockWrite("GET / HTTP/1.1\r\n"
16754 "Host: www.foo.com\r\n"
16755 "Connection: keep-alive\r\n\r\n"),
16756 MockWrite("POST / HTTP/1.1\r\n"
16757 "Host: www.foo.com\r\n"
16758 "Connection: keep-alive\r\n"
16759 "Content-Length: 3\r\n\r\n"),
16760 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16761 };
16762
16763 MockRead data_reads[] = {
16764 MockRead("HTTP/1.1 200 Peachy\r\n"
16765 "Content-Length: 14\r\n\r\n"),
16766 MockRead("first response"),
16767 MockRead("HTTP/1.1 400 Not OK\r\n"
16768 "Content-Length: 15\r\n\r\n"),
16769 MockRead("second response"),
16770 MockRead(SYNCHRONOUS, OK),
16771 };
16772 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16773 arraysize(data_writes));
16774 session_deps_.socket_factory->AddSocketDataProvider(&data);
16775
16776 TestCompletionCallback callback;
16777 HttpRequestInfo request1;
16778 request1.method = "GET";
16779 request1.url = GURL("http://www.foo.com/");
16780 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016781 request1.traffic_annotation =
16782 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416783
bnc87dcefc2017-05-25 12:47:5816784 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916785 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016786 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416788
16789 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116790 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416791
16792 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216793 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416794
wezca1070932016-05-26 20:30:5216795 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416796 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16797
16798 std::string response_data1;
16799 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116800 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416801 EXPECT_EQ("first response", response_data1);
16802 // Delete the transaction to release the socket back into the socket pool.
16803 trans1.reset();
16804
danakj1fd259a02016-04-16 03:17:0916805 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216806 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916807 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216808 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416809
16810 HttpRequestInfo request2;
16811 request2.method = "POST";
16812 request2.url = GURL("http://www.foo.com/");
16813 request2.upload_data_stream = &upload_data_stream;
16814 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016815 request2.traffic_annotation =
16816 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416817
bnc691fda62016-08-12 00:43:1616818 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016819 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416821
16822 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116823 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416824
bnc691fda62016-08-12 00:43:1616825 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216826 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416827
wezca1070932016-05-26 20:30:5216828 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416829 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16830
16831 std::string response_data2;
bnc691fda62016-08-12 00:43:1616832 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116833 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416834 EXPECT_EQ("second response", response_data2);
16835}
16836
bncd16676a2016-07-20 16:23:0116837TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416838 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916839 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216840 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916841 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216842 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416843
16844 HttpRequestInfo request;
16845 request.method = "POST";
16846 request.url = GURL("http://www.foo.com/");
16847 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016848 request.traffic_annotation =
16849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416850
danakj1fd259a02016-04-16 03:17:0916851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416853 // Send headers successfully, but get an error while sending the body.
16854 MockWrite data_writes[] = {
16855 MockWrite("POST / HTTP/1.1\r\n"
16856 "Host: www.foo.com\r\n"
16857 "Connection: keep-alive\r\n"
16858 "Content-Length: 3\r\n\r\n"
16859 "fo"),
16860 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16861 };
16862
16863 MockRead data_reads[] = {
16864 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16865 MockRead("hello world"),
16866 MockRead(SYNCHRONOUS, OK),
16867 };
16868 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16869 arraysize(data_writes));
16870 session_deps_.socket_factory->AddSocketDataProvider(&data);
16871
16872 TestCompletionCallback callback;
16873
tfarina42834112016-09-22 13:38:2016874 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416876
16877 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116878 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416879
bnc691fda62016-08-12 00:43:1616880 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216881 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416882
wezca1070932016-05-26 20:30:5216883 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416884 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16885
16886 std::string response_data;
bnc691fda62016-08-12 00:43:1616887 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116888 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416889 EXPECT_EQ("hello world", response_data);
16890}
16891
16892// This tests the more common case than the previous test, where headers and
16893// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116894TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716895 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416896
16897 HttpRequestInfo request;
16898 request.method = "POST";
16899 request.url = GURL("http://www.foo.com/");
16900 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016901 request.traffic_annotation =
16902 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416903
danakj1fd259a02016-04-16 03:17:0916904 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616905 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416906 // Send headers successfully, but get an error while sending the body.
16907 MockWrite data_writes[] = {
16908 MockWrite("POST / HTTP/1.1\r\n"
16909 "Host: www.foo.com\r\n"
16910 "Connection: keep-alive\r\n"
16911 "Transfer-Encoding: chunked\r\n\r\n"),
16912 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16913 };
16914
16915 MockRead data_reads[] = {
16916 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16917 MockRead("hello world"),
16918 MockRead(SYNCHRONOUS, OK),
16919 };
16920 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16921 arraysize(data_writes));
16922 session_deps_.socket_factory->AddSocketDataProvider(&data);
16923
16924 TestCompletionCallback callback;
16925
tfarina42834112016-09-22 13:38:2016926 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416928 // Make sure the headers are sent before adding a chunk. This ensures that
16929 // they can't be merged with the body in a single send. Not currently
16930 // necessary since a chunked body is never merged with headers, but this makes
16931 // the test more future proof.
16932 base::RunLoop().RunUntilIdle();
16933
mmenkecbc2b712014-10-09 20:29:0716934 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416935
16936 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116937 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416938
bnc691fda62016-08-12 00:43:1616939 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216940 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416941
wezca1070932016-05-26 20:30:5216942 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416943 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16944
16945 std::string response_data;
bnc691fda62016-08-12 00:43:1616946 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116947 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416948 EXPECT_EQ("hello world", response_data);
16949}
16950
bncd16676a2016-07-20 16:23:0116951TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916952 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216953 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916954 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216955 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416956
16957 HttpRequestInfo request;
16958 request.method = "POST";
16959 request.url = GURL("http://www.foo.com/");
16960 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016961 request.traffic_annotation =
16962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416963
danakj1fd259a02016-04-16 03:17:0916964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416966
16967 MockWrite data_writes[] = {
16968 MockWrite("POST / HTTP/1.1\r\n"
16969 "Host: www.foo.com\r\n"
16970 "Connection: keep-alive\r\n"
16971 "Content-Length: 3\r\n\r\n"),
16972 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16973 };
16974
16975 MockRead data_reads[] = {
16976 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16977 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16978 MockRead("hello world"),
16979 MockRead(SYNCHRONOUS, OK),
16980 };
16981 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16982 arraysize(data_writes));
16983 session_deps_.socket_factory->AddSocketDataProvider(&data);
16984
16985 TestCompletionCallback callback;
16986
tfarina42834112016-09-22 13:38:2016987 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416989
16990 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116991 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416992
bnc691fda62016-08-12 00:43:1616993 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216994 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416995
wezca1070932016-05-26 20:30:5216996 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416997 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16998
16999 std::string response_data;
bnc691fda62016-08-12 00:43:1617000 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117001 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417002 EXPECT_EQ("hello world", response_data);
17003}
17004
bncd16676a2016-07-20 16:23:0117005TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917006 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217007 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917008 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217009 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417010
17011 HttpRequestInfo request;
17012 request.method = "POST";
17013 request.url = GURL("http://www.foo.com/");
17014 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017015 request.traffic_annotation =
17016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417017
danakj1fd259a02016-04-16 03:17:0917018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417020 // Send headers successfully, but get an error while sending the body.
17021 MockWrite data_writes[] = {
17022 MockWrite("POST / HTTP/1.1\r\n"
17023 "Host: www.foo.com\r\n"
17024 "Connection: keep-alive\r\n"
17025 "Content-Length: 3\r\n\r\n"),
17026 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17027 };
17028
17029 MockRead data_reads[] = {
17030 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17031 MockRead("hello world"),
17032 MockRead(SYNCHRONOUS, OK),
17033 };
17034 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17035 arraysize(data_writes));
17036 session_deps_.socket_factory->AddSocketDataProvider(&data);
17037
17038 TestCompletionCallback callback;
17039
tfarina42834112016-09-22 13:38:2017040 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417042
17043 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117044 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417045}
17046
bncd16676a2016-07-20 16:23:0117047TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417048 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917049 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217050 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917051 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217052 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417053
17054 HttpRequestInfo request;
17055 request.method = "POST";
17056 request.url = GURL("http://www.foo.com/");
17057 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017058 request.traffic_annotation =
17059 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417060
danakj1fd259a02016-04-16 03:17:0917061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617062 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417063 // Send headers successfully, but get an error while sending the body.
17064 MockWrite data_writes[] = {
17065 MockWrite("POST / HTTP/1.1\r\n"
17066 "Host: www.foo.com\r\n"
17067 "Connection: keep-alive\r\n"
17068 "Content-Length: 3\r\n\r\n"),
17069 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17070 };
17071
17072 MockRead data_reads[] = {
17073 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17074 MockRead("HTTP/1.0 302 Redirect\r\n"),
17075 MockRead("Location: http://somewhere-else.com/\r\n"),
17076 MockRead("Content-Length: 0\r\n\r\n"),
17077 MockRead(SYNCHRONOUS, OK),
17078 };
17079 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17080 arraysize(data_writes));
17081 session_deps_.socket_factory->AddSocketDataProvider(&data);
17082
17083 TestCompletionCallback callback;
17084
tfarina42834112016-09-22 13:38:2017085 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417087
17088 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117089 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417090}
17091
bncd16676a2016-07-20 16:23:0117092TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917093 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217094 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917095 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217096 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417097
17098 HttpRequestInfo request;
17099 request.method = "POST";
17100 request.url = GURL("http://www.foo.com/");
17101 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017102 request.traffic_annotation =
17103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417104
danakj1fd259a02016-04-16 03:17:0917105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617106 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417107 // Send headers successfully, but get an error while sending the body.
17108 MockWrite data_writes[] = {
17109 MockWrite("POST / HTTP/1.1\r\n"
17110 "Host: www.foo.com\r\n"
17111 "Connection: keep-alive\r\n"
17112 "Content-Length: 3\r\n\r\n"),
17113 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17114 };
17115
17116 MockRead data_reads[] = {
17117 MockRead("HTTP 0.9 rocks!"),
17118 MockRead(SYNCHRONOUS, OK),
17119 };
17120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17121 arraysize(data_writes));
17122 session_deps_.socket_factory->AddSocketDataProvider(&data);
17123
17124 TestCompletionCallback callback;
17125
tfarina42834112016-09-22 13:38:2017126 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417128
17129 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117130 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417131}
17132
bncd16676a2016-07-20 16:23:0117133TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917134 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217135 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917136 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217137 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417138
17139 HttpRequestInfo request;
17140 request.method = "POST";
17141 request.url = GURL("http://www.foo.com/");
17142 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017143 request.traffic_annotation =
17144 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417145
danakj1fd259a02016-04-16 03:17:0917146 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417148 // Send headers successfully, but get an error while sending the body.
17149 MockWrite data_writes[] = {
17150 MockWrite("POST / HTTP/1.1\r\n"
17151 "Host: www.foo.com\r\n"
17152 "Connection: keep-alive\r\n"
17153 "Content-Length: 3\r\n\r\n"),
17154 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17155 };
17156
17157 MockRead data_reads[] = {
17158 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17159 MockRead(SYNCHRONOUS, OK),
17160 };
17161 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17162 arraysize(data_writes));
17163 session_deps_.socket_factory->AddSocketDataProvider(&data);
17164
17165 TestCompletionCallback callback;
17166
tfarina42834112016-09-22 13:38:2017167 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117168 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417169
17170 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117171 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417172}
17173
Bence Békydca6bd92018-01-30 13:43:0617174#if BUILDFLAG(ENABLE_WEBSOCKETS)
17175
17176namespace {
17177
17178void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17179 headers->SetHeader("Connection", "Upgrade");
17180 headers->SetHeader("Upgrade", "websocket");
17181 headers->SetHeader("Origin", "http://www.example.org");
17182 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617183}
17184
17185} // namespace
17186
17187TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
17188 // The same logic needs to be tested for both ws: and wss: schemes, but this
17189 // test is already parameterised on NextProto, so it uses a loop to verify
17190 // that the different schemes work.
17191 std::string test_cases[] = {"ws://www.example.org/",
17192 "wss://www.example.org/"};
17193 for (size_t i = 0; i < arraysize(test_cases); ++i) {
17194 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17195 HttpNetworkSessionPeer peer(session.get());
17196 FakeStreamFactory* fake_factory = new FakeStreamFactory();
17197 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
17198
17199 HttpRequestInfo request;
17200 request.method = "GET";
17201 request.url = GURL(test_cases[i]);
Ramin Halavatib5e433e62018-02-07 07:41:1017202 request.traffic_annotation =
17203 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617204
Bence Béky8d1c6052018-02-07 12:48:1517205 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17206
Bence Békydca6bd92018-01-30 13:43:0617207 HttpNetworkTransaction trans(LOW, session.get());
17208 trans.SetWebSocketHandshakeStreamCreateHelper(
17209 &websocket_stream_create_helper);
17210
17211 TestCompletionCallback callback;
17212 EXPECT_EQ(ERR_IO_PENDING,
17213 trans.Start(&request, callback.callback(), NetLogWithSource()));
17214
17215 base::WeakPtr<FakeStreamRequest> fake_request =
17216 fake_factory->last_stream_request();
17217 ASSERT_TRUE(fake_request);
17218 EXPECT_EQ(&websocket_stream_create_helper,
17219 fake_request->websocket_stream_create_helper());
17220 }
17221}
17222
Adam Rice425cf122015-01-19 06:18:2417223// Verify that proxy headers are not sent to the destination server when
17224// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117225TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417226 HttpRequestInfo request;
17227 request.method = "GET";
bncce36dca22015-04-21 22:11:2317228 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017229 request.traffic_annotation =
17230 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417231 AddWebSocketHeaders(&request.extra_headers);
17232
17233 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917234 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917235 ProxyResolutionService::CreateFixedFromPacResult(
17236 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417237
danakj1fd259a02016-04-16 03:17:0917238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417239
17240 // Since a proxy is configured, try to establish a tunnel.
17241 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717242 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17243 "Host: www.example.org:443\r\n"
17244 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417245
17246 // After calling trans->RestartWithAuth(), this is the request we should
17247 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717248 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17249 "Host: www.example.org:443\r\n"
17250 "Proxy-Connection: keep-alive\r\n"
17251 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417252
rsleevidb16bb02015-11-12 23:47:1717253 MockWrite("GET / HTTP/1.1\r\n"
17254 "Host: www.example.org\r\n"
17255 "Connection: Upgrade\r\n"
17256 "Upgrade: websocket\r\n"
17257 "Origin: http://www.example.org\r\n"
17258 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517259 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17260 "Sec-WebSocket-Extensions: permessage-deflate; "
17261 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417262
17263 // The proxy responds to the connect with a 407, using a persistent
17264 // connection.
17265 MockRead data_reads[] = {
17266 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517267 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17268 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17269 "Content-Length: 0\r\n"
17270 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417271
17272 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17273
Bence Béky8d1c6052018-02-07 12:48:1517274 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17275 "Upgrade: websocket\r\n"
17276 "Connection: Upgrade\r\n"
17277 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417278
17279 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17280 arraysize(data_writes));
17281 session_deps_.socket_factory->AddSocketDataProvider(&data);
17282 SSLSocketDataProvider ssl(ASYNC, OK);
17283 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17284
Bence Béky8d1c6052018-02-07 12:48:1517285 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17286
bnc87dcefc2017-05-25 12:47:5817287 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917288 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417289 trans->SetWebSocketHandshakeStreamCreateHelper(
17290 &websocket_stream_create_helper);
17291
17292 {
17293 TestCompletionCallback callback;
17294
tfarina42834112016-09-22 13:38:2017295 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417297
17298 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117299 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417300 }
17301
17302 const HttpResponseInfo* response = trans->GetResponseInfo();
17303 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217304 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417305 EXPECT_EQ(407, response->headers->response_code());
17306
17307 {
17308 TestCompletionCallback callback;
17309
17310 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17311 callback.callback());
robpercival214763f2016-07-01 23:27:0117312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417313
17314 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117315 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417316 }
17317
17318 response = trans->GetResponseInfo();
17319 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217320 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417321
17322 EXPECT_EQ(101, response->headers->response_code());
17323
17324 trans.reset();
17325 session->CloseAllConnections();
17326}
17327
17328// Verify that proxy headers are not sent to the destination server when
17329// establishing a tunnel for an insecure WebSocket connection.
17330// This requires the authentication info to be injected into the auth cache
17331// due to crbug.com/395064
17332// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117333TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417334 HttpRequestInfo request;
17335 request.method = "GET";
bncce36dca22015-04-21 22:11:2317336 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017337 request.traffic_annotation =
17338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417339 AddWebSocketHeaders(&request.extra_headers);
17340
17341 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917342 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917343 ProxyResolutionService::CreateFixedFromPacResult(
17344 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417345
danakj1fd259a02016-04-16 03:17:0917346 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417347
17348 MockWrite data_writes[] = {
17349 // Try to establish a tunnel for the WebSocket connection, with
17350 // credentials. Because WebSockets have a separate set of socket pools,
17351 // they cannot and will not use the same TCP/IP connection as the
17352 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517353 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17354 "Host: www.example.org:80\r\n"
17355 "Proxy-Connection: keep-alive\r\n"
17356 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417357
Bence Béky8d1c6052018-02-07 12:48:1517358 MockWrite("GET / HTTP/1.1\r\n"
17359 "Host: www.example.org\r\n"
17360 "Connection: Upgrade\r\n"
17361 "Upgrade: websocket\r\n"
17362 "Origin: http://www.example.org\r\n"
17363 "Sec-WebSocket-Version: 13\r\n"
17364 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17365 "Sec-WebSocket-Extensions: permessage-deflate; "
17366 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417367
17368 MockRead data_reads[] = {
17369 // HTTP CONNECT with credentials.
17370 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17371
17372 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517373 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17374 "Upgrade: websocket\r\n"
17375 "Connection: Upgrade\r\n"
17376 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417377
17378 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17379 arraysize(data_writes));
17380 session_deps_.socket_factory->AddSocketDataProvider(&data);
17381
17382 session->http_auth_cache()->Add(
17383 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17384 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17385
Bence Béky8d1c6052018-02-07 12:48:1517386 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17387
bnc87dcefc2017-05-25 12:47:5817388 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917389 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417390 trans->SetWebSocketHandshakeStreamCreateHelper(
17391 &websocket_stream_create_helper);
17392
17393 TestCompletionCallback callback;
17394
tfarina42834112016-09-22 13:38:2017395 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417397
17398 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117399 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417400
17401 const HttpResponseInfo* response = trans->GetResponseInfo();
17402 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217403 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417404
17405 EXPECT_EQ(101, response->headers->response_code());
17406
17407 trans.reset();
17408 session->CloseAllConnections();
17409}
17410
Bence Békydca6bd92018-01-30 13:43:0617411#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17412
bncd16676a2016-07-20 16:23:0117413TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917414 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217415 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917416 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217417 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217418
17419 HttpRequestInfo request;
17420 request.method = "POST";
17421 request.url = GURL("http://www.foo.com/");
17422 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017423 request.traffic_annotation =
17424 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217425
danakj1fd259a02016-04-16 03:17:0917426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617427 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217428 MockWrite data_writes[] = {
17429 MockWrite("POST / HTTP/1.1\r\n"
17430 "Host: www.foo.com\r\n"
17431 "Connection: keep-alive\r\n"
17432 "Content-Length: 3\r\n\r\n"),
17433 MockWrite("foo"),
17434 };
17435
17436 MockRead data_reads[] = {
17437 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17438 MockRead(SYNCHRONOUS, OK),
17439 };
17440 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17441 arraysize(data_writes));
17442 session_deps_.socket_factory->AddSocketDataProvider(&data);
17443
17444 TestCompletionCallback callback;
17445
17446 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017447 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117448 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217449
17450 std::string response_data;
bnc691fda62016-08-12 00:43:1617451 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217452
17453 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617454 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217455 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617456 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217457}
17458
bncd16676a2016-07-20 16:23:0117459TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917460 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217461 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917462 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217463 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217464
17465 HttpRequestInfo request;
17466 request.method = "POST";
17467 request.url = GURL("http://www.foo.com/");
17468 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017469 request.traffic_annotation =
17470 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217471
danakj1fd259a02016-04-16 03:17:0917472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217474 MockWrite data_writes[] = {
17475 MockWrite("POST / HTTP/1.1\r\n"
17476 "Host: www.foo.com\r\n"
17477 "Connection: keep-alive\r\n"
17478 "Content-Length: 3\r\n\r\n"),
17479 MockWrite("foo"),
17480 };
17481
17482 MockRead data_reads[] = {
17483 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17484 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17485 MockRead(SYNCHRONOUS, OK),
17486 };
17487 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17488 arraysize(data_writes));
17489 session_deps_.socket_factory->AddSocketDataProvider(&data);
17490
17491 TestCompletionCallback callback;
17492
17493 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017494 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117495 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217496
17497 std::string response_data;
bnc691fda62016-08-12 00:43:1617498 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217499
17500 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617501 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217502 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617503 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217504}
17505
bncd16676a2016-07-20 16:23:0117506TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217507 ChunkedUploadDataStream upload_data_stream(0);
17508
17509 HttpRequestInfo request;
17510 request.method = "POST";
17511 request.url = GURL("http://www.foo.com/");
17512 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017513 request.traffic_annotation =
17514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217515
danakj1fd259a02016-04-16 03:17:0917516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217518 // Send headers successfully, but get an error while sending the body.
17519 MockWrite data_writes[] = {
17520 MockWrite("POST / HTTP/1.1\r\n"
17521 "Host: www.foo.com\r\n"
17522 "Connection: keep-alive\r\n"
17523 "Transfer-Encoding: chunked\r\n\r\n"),
17524 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17525 };
17526
17527 MockRead data_reads[] = {
17528 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17529 MockRead(SYNCHRONOUS, OK),
17530 };
17531 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17532 arraysize(data_writes));
17533 session_deps_.socket_factory->AddSocketDataProvider(&data);
17534
17535 TestCompletionCallback callback;
17536
17537 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017538 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217539
17540 base::RunLoop().RunUntilIdle();
17541 upload_data_stream.AppendData("f", 1, false);
17542
17543 base::RunLoop().RunUntilIdle();
17544 upload_data_stream.AppendData("oo", 2, true);
17545
robpercival214763f2016-07-01 23:27:0117546 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217547
17548 std::string response_data;
bnc691fda62016-08-12 00:43:1617549 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217550
17551 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617552 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217553 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617554 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217555}
17556
rdsmith1d343be52016-10-21 20:37:5017557// Confirm that transactions whose throttle is created in (and stays in)
17558// the unthrottled state are not blocked.
17559TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17560 TestNetworkStreamThrottler* throttler(nullptr);
17561 std::unique_ptr<HttpNetworkSession> session(
17562 CreateSessionWithThrottler(&session_deps_, &throttler));
17563
17564 // Send a simple request and make sure it goes through.
17565 HttpRequestInfo request;
17566 request.method = "GET";
17567 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017568 request.traffic_annotation =
17569 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017570
bnc87dcefc2017-05-25 12:47:5817571 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917572 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017573
17574 MockWrite data_writes[] = {
17575 MockWrite("GET / HTTP/1.1\r\n"
17576 "Host: www.example.org\r\n"
17577 "Connection: keep-alive\r\n\r\n"),
17578 };
17579 MockRead data_reads[] = {
17580 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17581 MockRead(SYNCHRONOUS, OK),
17582 };
17583 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17584 arraysize(data_writes));
17585 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17586
17587 TestCompletionCallback callback;
17588 trans->Start(&request, callback.callback(), NetLogWithSource());
17589 EXPECT_EQ(OK, callback.WaitForResult());
17590}
17591
17592// Confirm requests can be blocked by a throttler, and are resumed
17593// when the throttle is unblocked.
17594TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17595 TestNetworkStreamThrottler* throttler(nullptr);
17596 std::unique_ptr<HttpNetworkSession> session(
17597 CreateSessionWithThrottler(&session_deps_, &throttler));
17598
17599 // Send a simple request and make sure it goes through.
17600 HttpRequestInfo request;
17601 request.method = "GET";
17602 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017603 request.traffic_annotation =
17604 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017605
17606 MockWrite data_writes[] = {
17607 MockWrite("GET / HTTP/1.1\r\n"
17608 "Host: www.example.org\r\n"
17609 "Connection: keep-alive\r\n\r\n"),
17610 };
17611 MockRead data_reads[] = {
17612 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17613 MockRead(SYNCHRONOUS, OK),
17614 };
17615 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17616 arraysize(data_writes));
17617 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17618
17619 // Start a request that will be throttled at start; confirm it
17620 // doesn't complete.
17621 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817622 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917623 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017624
17625 TestCompletionCallback callback;
17626 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17627 EXPECT_EQ(ERR_IO_PENDING, rv);
17628
17629 base::RunLoop().RunUntilIdle();
17630 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17631 EXPECT_FALSE(callback.have_result());
17632
17633 // Confirm the request goes on to complete when unthrottled.
17634 throttler->UnthrottleAllRequests();
17635 base::RunLoop().RunUntilIdle();
17636 ASSERT_TRUE(callback.have_result());
17637 EXPECT_EQ(OK, callback.WaitForResult());
17638}
17639
17640// Destroy a request while it's throttled.
17641TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17642 TestNetworkStreamThrottler* throttler(nullptr);
17643 std::unique_ptr<HttpNetworkSession> session(
17644 CreateSessionWithThrottler(&session_deps_, &throttler));
17645
17646 // Send a simple request and make sure it goes through.
17647 HttpRequestInfo request;
17648 request.method = "GET";
17649 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017650 request.traffic_annotation =
17651 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017652
17653 MockWrite data_writes[] = {
17654 MockWrite("GET / HTTP/1.1\r\n"
17655 "Host: www.example.org\r\n"
17656 "Connection: keep-alive\r\n\r\n"),
17657 };
17658 MockRead data_reads[] = {
17659 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17660 MockRead(SYNCHRONOUS, OK),
17661 };
17662 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17663 arraysize(data_writes));
17664 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17665
17666 // Start a request that will be throttled at start; confirm it
17667 // doesn't complete.
17668 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817669 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917670 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017671
17672 TestCompletionCallback callback;
17673 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17674 EXPECT_EQ(ERR_IO_PENDING, rv);
17675
17676 base::RunLoop().RunUntilIdle();
17677 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17678 EXPECT_FALSE(callback.have_result());
17679
17680 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17681 trans.reset();
17682 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17683}
17684
17685// Confirm the throttler receives SetPriority calls.
17686TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17687 TestNetworkStreamThrottler* throttler(nullptr);
17688 std::unique_ptr<HttpNetworkSession> session(
17689 CreateSessionWithThrottler(&session_deps_, &throttler));
17690
17691 // Send a simple request and make sure it goes through.
17692 HttpRequestInfo request;
17693 request.method = "GET";
17694 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017695 request.traffic_annotation =
17696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017697
17698 MockWrite data_writes[] = {
17699 MockWrite("GET / HTTP/1.1\r\n"
17700 "Host: www.example.org\r\n"
17701 "Connection: keep-alive\r\n\r\n"),
17702 };
17703 MockRead data_reads[] = {
17704 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17705 MockRead(SYNCHRONOUS, OK),
17706 };
17707 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17708 arraysize(data_writes));
17709 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17710
17711 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917712 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017713 // Start the transaction to associate a throttle with it.
17714 TestCompletionCallback callback;
17715 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17716 EXPECT_EQ(ERR_IO_PENDING, rv);
17717
17718 EXPECT_EQ(0, throttler->num_set_priority_calls());
17719 trans->SetPriority(LOW);
17720 EXPECT_EQ(1, throttler->num_set_priority_calls());
17721 EXPECT_EQ(LOW, throttler->last_priority_set());
17722
17723 throttler->UnthrottleAllRequests();
17724 base::RunLoop().RunUntilIdle();
17725 ASSERT_TRUE(callback.have_result());
17726 EXPECT_EQ(OK, callback.WaitForResult());
17727}
17728
17729// Confirm that unthrottling from a SetPriority call by the
17730// throttler works properly.
17731TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17732 TestNetworkStreamThrottler* throttler(nullptr);
17733 std::unique_ptr<HttpNetworkSession> session(
17734 CreateSessionWithThrottler(&session_deps_, &throttler));
17735
17736 // Send a simple request and make sure it goes through.
17737 HttpRequestInfo request;
17738 request.method = "GET";
17739 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017740 request.traffic_annotation =
17741 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017742
17743 MockWrite data_writes[] = {
17744 MockWrite("GET / HTTP/1.1\r\n"
17745 "Host: www.example.org\r\n"
17746 "Connection: keep-alive\r\n\r\n"),
17747 };
17748 MockRead data_reads[] = {
17749 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17750 MockRead(SYNCHRONOUS, OK),
17751 };
17752 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17753 arraysize(data_writes));
17754 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17755
17756 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17757 data_writes, arraysize(data_writes));
17758 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17759
17760 // Start a request that will be throttled at start; confirm it
17761 // doesn't complete.
17762 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817763 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917764 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017765
17766 TestCompletionCallback callback;
17767 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17768 EXPECT_EQ(ERR_IO_PENDING, rv);
17769
17770 base::RunLoop().RunUntilIdle();
17771 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17772 EXPECT_FALSE(callback.have_result());
17773
17774 // Create a new request, call SetPriority on it to unthrottle,
17775 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917776 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017777 throttler->set_priority_change_closure(
17778 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17779 base::Unretained(throttler)));
17780
17781 // Start the transaction to associate a throttle with it.
17782 TestCompletionCallback callback1;
17783 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17784 EXPECT_EQ(ERR_IO_PENDING, rv);
17785
17786 trans1->SetPriority(IDLE);
17787
17788 base::RunLoop().RunUntilIdle();
17789 ASSERT_TRUE(callback.have_result());
17790 EXPECT_EQ(OK, callback.WaitForResult());
17791 ASSERT_TRUE(callback1.have_result());
17792 EXPECT_EQ(OK, callback1.WaitForResult());
17793}
17794
17795// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817796void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017797
17798// Confirm that destroying a transaction from a SetPriority call by the
17799// throttler works properly.
17800TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17801 TestNetworkStreamThrottler* throttler(nullptr);
17802 std::unique_ptr<HttpNetworkSession> session(
17803 CreateSessionWithThrottler(&session_deps_, &throttler));
17804
17805 // Send a simple request and make sure it goes through.
17806 HttpRequestInfo request;
17807 request.method = "GET";
17808 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017809 request.traffic_annotation =
17810 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017811
17812 MockWrite data_writes[] = {
17813 MockWrite("GET / HTTP/1.1\r\n"
17814 "Host: www.example.org\r\n"
17815 "Connection: keep-alive\r\n\r\n"),
17816 };
17817 MockRead data_reads[] = {
17818 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17819 MockRead(SYNCHRONOUS, OK),
17820 };
17821 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17822 arraysize(data_writes));
17823 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17824
17825 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17826 data_writes, arraysize(data_writes));
17827 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17828
17829 // Start a request that will be throttled at start; confirm it
17830 // doesn't complete.
17831 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817832 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917833 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017834
17835 TestCompletionCallback callback;
17836 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17837 EXPECT_EQ(ERR_IO_PENDING, rv);
17838
17839 base::RunLoop().RunUntilIdle();
17840 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17841 EXPECT_FALSE(callback.have_result());
17842
17843 // Arrange for the set priority call on the above transaction to delete
17844 // the transaction.
bnc87dcefc2017-05-25 12:47:5817845 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017846 throttler->set_priority_change_closure(
17847 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17848
17849 // Call it and check results (partially a "doesn't crash" test).
17850 trans_ptr->SetPriority(IDLE);
17851 trans_ptr = nullptr; // No longer a valid pointer.
17852
17853 base::RunLoop().RunUntilIdle();
17854 ASSERT_FALSE(callback.have_result());
17855}
17856
nharperb7441ef2016-01-25 23:54:1417857#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117858TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417859 const std::string https_url = "https://www.example.com";
17860 HttpRequestInfo request;
17861 request.url = GURL(https_url);
17862 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:1017863 request.traffic_annotation =
17864 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417865
17866 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917867 ssl.ssl_info.token_binding_negotiated = true;
17868 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617869 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17871
bnc42331402016-07-25 13:36:1517872 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117873 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17874 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417875 MockRead(ASYNC, ERR_IO_PENDING)};
17876 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17877 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817878 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917879 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917880 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417881
17882 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17883 TestCompletionCallback callback;
17884 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017885 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017886
17887 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417888
17889 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17890 HttpRequestHeaders headers;
17891 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17892 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17893}
17894#endif // !defined(OS_IOS)
17895
eustasc7d27da2017-04-06 10:33:2017896void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17897 const std::string& accept_encoding,
17898 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317899 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017900 bool should_match) {
17901 HttpRequestInfo request;
17902 request.method = "GET";
17903 request.url = GURL("http://www.foo.com/");
17904 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17905 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1017906 request.traffic_annotation =
17907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017908
17909 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17910 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17911 // Send headers successfully, but get an error while sending the body.
17912 MockWrite data_writes[] = {
17913 MockWrite("GET / HTTP/1.1\r\n"
17914 "Host: www.foo.com\r\n"
17915 "Connection: keep-alive\r\n"
17916 "Accept-Encoding: "),
17917 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17918 };
17919
sky50576f32017-05-01 19:28:0317920 std::string response_code = "200 OK";
17921 std::string extra;
17922 if (!location.empty()) {
17923 response_code = "301 Redirect\r\nLocation: ";
17924 response_code.append(location);
17925 }
17926
eustasc7d27da2017-04-06 10:33:2017927 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317928 MockRead("HTTP/1.0 "),
17929 MockRead(response_code.data()),
17930 MockRead("\r\nContent-Encoding: "),
17931 MockRead(content_encoding.data()),
17932 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017933 MockRead(SYNCHRONOUS, OK),
17934 };
17935 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17936 arraysize(data_writes));
17937 session_deps->socket_factory->AddSocketDataProvider(&data);
17938
17939 TestCompletionCallback callback;
17940
17941 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17943
17944 rv = callback.WaitForResult();
17945 if (should_match) {
17946 EXPECT_THAT(rv, IsOk());
17947 } else {
17948 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17949 }
17950}
17951
17952TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317953 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017954}
17955
17956TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317957 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17958 true);
eustasc7d27da2017-04-06 10:33:2017959}
17960
17961TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17962 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317963 "", false);
17964}
17965
17966TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17967 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17968 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017969}
17970
xunjieli96f2a402017-06-05 17:24:2717971TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17972 ProxyConfig proxy_config;
17973 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17974 proxy_config.set_pac_mandatory(true);
17975 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917976 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917977 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17978 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0417979 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717980
17981 HttpRequestInfo request;
17982 request.method = "GET";
17983 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017984 request.traffic_annotation =
17985 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717986
17987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17989
17990 TestCompletionCallback callback;
17991
17992 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17994 EXPECT_THAT(callback.WaitForResult(),
17995 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17996}
17997
17998TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17999 ProxyConfig proxy_config;
18000 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18001 proxy_config.set_pac_mandatory(true);
18002 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18003 new MockAsyncProxyResolverFactory(false);
18004 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918005 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918006 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18007 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918008 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718009 HttpRequestInfo request;
18010 request.method = "GET";
18011 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018012 request.traffic_annotation =
18013 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718014
18015 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18016 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18017
18018 TestCompletionCallback callback;
18019 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18021
18022 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18023 ERR_FAILED, &resolver);
18024 EXPECT_THAT(callback.WaitForResult(),
18025 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18026}
18027
18028TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918029 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918030 ProxyResolutionService::CreateFixedFromPacResult(
18031 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718032 session_deps_.enable_quic = false;
18033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18034
18035 HttpRequestInfo request;
18036 request.method = "GET";
18037 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018038 request.traffic_annotation =
18039 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718040
18041 TestCompletionCallback callback;
18042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18043 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18045
18046 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18047}
18048
[email protected]89ceba9a2009-03-21 03:46:0618049} // namespace net