blob: 2ef3c9d1afe0dfe74667c8f39b49cc96962a3ff1 [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"
75#include "net/proxy_resolution/proxy_resolver.h"
76#include "net/proxy_resolution/proxy_resolver_factory.h"
77#include "net/proxy_resolution/proxy_service.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.
385 int CreateProxyResolver(
386 const scoped_refptr<ProxyResolverScriptData>& script_data,
387 std::unique_ptr<ProxyResolver>* result,
388 const CompletionCallback& callback,
389 std::unique_ptr<Request>* request) override {
390 return ERR_PAC_SCRIPT_FAILED;
391 }
392};
393
[email protected]448d4ca52012-03-04 04:12:23394} // namespace
395
bncd16676a2016-07-20 16:23:01396class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03397 public:
bncd16676a2016-07-20 16:23:01398 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03399 // Important to restore the per-pool limit first, since the pool limit must
400 // always be greater than group limit, and the tests reduce both limits.
401 ClientSocketPoolManager::set_max_sockets_per_pool(
402 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
403 ClientSocketPoolManager::set_max_sockets_per_group(
404 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
405 }
406
[email protected]e3ceb682011-06-28 23:55:46407 protected:
[email protected]23e482282013-06-14 16:08:02408 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15409 : ssl_(ASYNC, OK),
410 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03411 HttpNetworkSession::NORMAL_SOCKET_POOL)),
412 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
413 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28414 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03415 }
[email protected]bb88e1d32013-05-03 23:11:07416
[email protected]e3ceb682011-06-28 23:55:46417 struct SimpleGetHelperResult {
418 int rv;
419 std::string status_line;
420 std::string response_data;
sclittlefb249892015-09-10 21:33:22421 int64_t total_received_bytes;
422 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25423 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47424 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59425 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46426 };
427
dcheng67be2b1f2014-10-27 21:47:29428 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50429 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55430 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54431 }
432
dcheng67be2b1f2014-10-27 21:47:29433 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50434 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55435 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09436 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55437 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09438 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50439 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55440 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09441 }
442
[email protected]202965992011-12-07 23:04:51443 // Either |write_failure| specifies a write failure or |read_failure|
444 // specifies a read failure when using a reused socket. In either case, the
445 // failure should cause the network transaction to resend the request, and the
446 // other argument should be NULL.
447 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
448 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52449
[email protected]a34f61ee2014-03-18 20:59:49450 // Either |write_failure| specifies a write failure or |read_failure|
451 // specifies a read failure when using a reused socket. In either case, the
452 // failure should cause the network transaction to resend the request, and the
453 // other argument should be NULL.
454 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10455 const MockRead* read_failure,
456 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49457
[email protected]5a60c8b2011-10-19 20:14:29458 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
459 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15460 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]ff007e162009-05-23 09:13:15462 HttpRequestInfo request;
463 request.method = "GET";
bncce36dca22015-04-21 22:11:23464 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10465 request.traffic_annotation =
466 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52467
vishal.b62985ca92015-04-17 08:45:51468 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07469 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27472
[email protected]5a60c8b2011-10-19 20:14:29473 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07474 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29475 }
initial.commit586acc5fe2008-07-26 22:42:52476
[email protected]49639fa2011-12-20 23:22:41477 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52478
eroman24bc6a12015-05-06 19:55:48479 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16480 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52482
[email protected]ff007e162009-05-23 09:13:15483 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16484 out.total_received_bytes = trans.GetTotalReceivedBytes();
485 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25486
487 // Even in the failure cases that use this function, connections are always
488 // successfully established before the error.
bnc691fda62016-08-12 00:43:16489 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25490 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
491
[email protected]ff007e162009-05-23 09:13:15492 if (out.rv != OK)
493 return out;
494
bnc691fda62016-08-12 00:43:16495 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50496 // Can't use ASSERT_* inside helper functions like this, so
497 // return an error.
wezca1070932016-05-26 20:30:52498 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50499 out.rv = ERR_UNEXPECTED;
500 return out;
501 }
[email protected]ff007e162009-05-23 09:13:15502 out.status_line = response->headers->GetStatusLine();
503
[email protected]80a09a82012-11-16 17:40:06504 EXPECT_EQ("127.0.0.1", response->socket_address.host());
505 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19506
ttuttled9dbc652015-09-29 20:00:59507 bool got_endpoint =
bnc691fda62016-08-12 00:43:16508 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59509 EXPECT_EQ(got_endpoint,
510 out.remote_endpoint_after_start.address().size() > 0);
511
bnc691fda62016-08-12 00:43:16512 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01513 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40514
mmenke43758e62015-05-04 21:09:46515 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40516 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39517 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00518 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
519 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39520 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00521 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
522 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15523
[email protected]f3da152d2012-06-02 01:00:57524 std::string line;
525 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
526 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
527
[email protected]79e1fd62013-06-20 06:50:04528 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16529 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04530 std::string value;
531 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23532 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04533 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
534 EXPECT_EQ("keep-alive", value);
535
536 std::string response_headers;
537 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23538 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04539 response_headers);
[email protected]3deb9a52010-11-11 00:24:40540
bnc691fda62016-08-12 00:43:16541 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22542 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16543 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22544
bnc691fda62016-08-12 00:43:16545 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47546 return out;
[email protected]ff007e162009-05-23 09:13:15547 }
initial.commit586acc5fe2008-07-26 22:42:52548
[email protected]5a60c8b2011-10-19 20:14:29549 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
550 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22551 MockWrite data_writes[] = {
552 MockWrite("GET / HTTP/1.1\r\n"
553 "Host: www.example.org\r\n"
554 "Connection: keep-alive\r\n\r\n"),
555 };
[email protected]5a60c8b2011-10-19 20:14:29556
sclittlefb249892015-09-10 21:33:22557 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
558 arraysize(data_writes));
559 StaticSocketDataProvider* data[] = {&reads};
560 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
561
562 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
563 out.total_sent_bytes);
564 return out;
[email protected]b8015c42013-12-24 15:18:19565 }
566
bnc032658ba2016-09-26 18:17:15567 void AddSSLSocketData() {
568 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49569 ssl_.ssl_info.cert =
570 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
571 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15572 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
573 }
574
[email protected]ff007e162009-05-23 09:13:15575 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
576 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52577
[email protected]ff007e162009-05-23 09:13:15578 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07579
580 void BypassHostCacheOnRefreshHelper(int load_flags);
581
582 void CheckErrorIsPassedBack(int error, IoMode mode);
583
[email protected]4bd46222013-05-14 19:32:23584 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07585 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15586 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03587
588 // Original socket limits. Some tests set these. Safest to always restore
589 // them once each test has been run.
590 int old_max_group_sockets_;
591 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15592};
[email protected]231d5a32008-09-13 00:45:27593
[email protected]448d4ca52012-03-04 04:12:23594namespace {
595
ryansturm49a8cb12016-06-15 16:51:09596class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27597 public:
ryansturm49a8cb12016-06-15 16:51:09598 BeforeHeadersSentHandler()
599 : observed_before_headers_sent_with_proxy_(false),
600 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27601
ryansturm49a8cb12016-06-15 16:51:09602 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
603 HttpRequestHeaders* request_headers) {
604 observed_before_headers_sent_ = true;
605 if (!proxy_info.is_http() && !proxy_info.is_https() &&
606 !proxy_info.is_quic()) {
607 return;
608 }
609 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27610 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
611 }
612
ryansturm49a8cb12016-06-15 16:51:09613 bool observed_before_headers_sent_with_proxy() const {
614 return observed_before_headers_sent_with_proxy_;
615 }
616
617 bool observed_before_headers_sent() const {
618 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27619 }
620
621 std::string observed_proxy_server_uri() const {
622 return observed_proxy_server_uri_;
623 }
624
625 private:
ryansturm49a8cb12016-06-15 16:51:09626 bool observed_before_headers_sent_with_proxy_;
627 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27628 std::string observed_proxy_server_uri_;
629
ryansturm49a8cb12016-06-15 16:51:09630 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27631};
632
[email protected]15a5ccf82008-10-23 19:57:43633// Fill |str| with a long header list that consumes >= |size| bytes.
634void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51635 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19636 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
637 const int sizeof_row = strlen(row);
638 const int num_rows = static_cast<int>(
639 ceil(static_cast<float>(size) / sizeof_row));
640 const int sizeof_data = num_rows * sizeof_row;
641 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43642 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51643
[email protected]4ddaf2502008-10-23 18:26:19644 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43645 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19646}
647
thakis84dff942015-07-28 20:47:38648#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09649uint64_t MockGetMSTime() {
650 // Tue, 23 May 2017 20:13:07 +0000
651 return 131400439870000000;
652}
653
[email protected]385a4672009-03-11 22:21:29654// Alternative functions that eliminate randomness and dependency on the local
655// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37656void MockGenerateRandom(uint8_t* output, size_t n) {
657 // This is set to 0xaa because the client challenge for testing in
658 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
659 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29660}
661
[email protected]fe2bc6a2009-03-23 16:52:20662std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37663 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29664}
thakis84dff942015-07-28 20:47:38665#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29666
[email protected]e60e47a2010-07-14 03:37:18667template<typename ParentPool>
668class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31669 public:
[email protected]9e1bdd32011-02-03 21:48:34670 CaptureGroupNameSocketPool(HostResolver* host_resolver,
671 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18672
[email protected]d80a4322009-08-14 07:07:49673 const std::string last_group_name_received() const {
674 return last_group_name_;
675 }
676
Tarun Bansal162eabe52018-01-20 01:16:39677 bool socket_requested() const { return socket_requested_; }
678
dmichaeld6e570d2014-12-18 22:30:57679 int RequestSocket(const std::string& group_name,
680 const void* socket_params,
681 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54682 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15683 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57684 ClientSocketHandle* handle,
685 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20686 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31687 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39688 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31689 return ERR_IO_PENDING;
690 }
dmichaeld6e570d2014-12-18 22:30:57691 void CancelRequest(const std::string& group_name,
692 ClientSocketHandle* handle) override {}
693 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09694 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57695 int id) override {}
696 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23697 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57698 int IdleSocketCount() const override { return 0; }
699 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31700 return 0;
701 }
dmichaeld6e570d2014-12-18 22:30:57702 LoadState GetLoadState(const std::string& group_name,
703 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31704 return LOAD_STATE_IDLE;
705 }
dmichaeld6e570d2014-12-18 22:30:57706 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26707 return base::TimeDelta();
708 }
[email protected]d80a4322009-08-14 07:07:49709
710 private:
[email protected]04e5be32009-06-26 20:00:31711 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39712 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31713};
714
[email protected]ab739042011-04-07 15:22:28715typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
716CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13717typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
718CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06719typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11720CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18721typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
722CaptureGroupNameSSLSocketPool;
723
rkaplowd90695c2015-03-25 22:12:41724template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18725CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34726 HostResolver* host_resolver,
727 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21728 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18729
hashimoto0d3e4fb2015-01-09 05:02:50730template <>
[email protected]2df19bb2010-08-25 20:13:46731CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21732 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34733 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09734 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46735
[email protected]007b3f82013-04-09 08:46:45736template <>
[email protected]e60e47a2010-07-14 03:37:18737CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21738 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34739 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45740 : SSLClientSocketPool(0,
741 0,
[email protected]007b3f82013-04-09 08:46:45742 cert_verifier,
743 NULL,
744 NULL,
[email protected]284303b62013-11-28 15:11:54745 NULL,
eranm6571b2b2014-12-03 15:53:23746 NULL,
[email protected]007b3f82013-04-09 08:46:45747 std::string(),
748 NULL,
749 NULL,
750 NULL,
751 NULL,
752 NULL,
[email protected]8e458552014-08-05 00:02:15753 NULL) {
754}
[email protected]2227c692010-05-04 15:36:11755
[email protected]231d5a32008-09-13 00:45:27756//-----------------------------------------------------------------------------
757
[email protected]79cb5c12011-09-12 13:12:04758// Helper functions for validating that AuthChallengeInfo's are correctly
759// configured for common cases.
760bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
761 if (!auth_challenge)
762 return false;
763 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43764 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04765 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19766 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04767 return true;
768}
769
770bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
771 if (!auth_challenge)
772 return false;
773 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43774 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
775 EXPECT_EQ("MyRealm1", auth_challenge->realm);
776 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
777 return true;
778}
779
780bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
781 if (!auth_challenge)
782 return false;
783 EXPECT_TRUE(auth_challenge->is_proxy);
784 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04785 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19786 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04787 return true;
788}
789
790bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
791 if (!auth_challenge)
792 return false;
793 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43794 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04795 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19796 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04797 return true;
798}
799
thakis84dff942015-07-28 20:47:38800#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04801bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
802 if (!auth_challenge)
803 return false;
804 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55805 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04806 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19807 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04808 return true;
809}
thakis84dff942015-07-28 20:47:38810#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04811
[email protected]448d4ca52012-03-04 04:12:23812} // namespace
813
bncd16676a2016-07-20 16:23:01814TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27817}
818
bncd16676a2016-07-20 16:23:01819TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27820 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35821 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
822 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06823 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27824 };
[email protected]31a2bfe2010-02-09 08:03:39825 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
826 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01827 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27828 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
829 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22830 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
831 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47832 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59833
834 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27835}
836
837// Response with no status line.
bncd16676a2016-07-20 16:23:01838TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27839 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35840 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06841 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27842 };
[email protected]31a2bfe2010-02-09 08:03:39843 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
844 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41845 EXPECT_THAT(out.rv, IsOk());
846 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
847 EXPECT_EQ("hello world", out.response_data);
848 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
849 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27850}
851
mmenkea7da6da2016-09-01 21:56:52852// Response with no status line, and a weird port. Should fail by default.
853TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
854 MockRead data_reads[] = {
855 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
856 };
857
858 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
859 session_deps_.socket_factory->AddSocketDataProvider(&data);
860
861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
862
krasinc06a72a2016-12-21 03:42:46863 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58864 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19865 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52866
mmenkea7da6da2016-09-01 21:56:52867 request.method = "GET";
868 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10869 request.traffic_annotation =
870 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
871
mmenkea7da6da2016-09-01 21:56:52872 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20873 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52874 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
875}
876
Shivani Sharmafdcaefd2017-11-02 00:12:26877// Tests that request info can be destroyed after the headers phase is complete.
878TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
880 auto trans =
881 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
882
883 MockRead data_reads[] = {
884 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
885 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
886 };
887 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
888 session_deps_.socket_factory->AddSocketDataProvider(&data);
889
890 TestCompletionCallback callback;
891
892 {
893 auto request = std::make_unique<HttpRequestInfo>();
894 request->method = "GET";
895 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10896 request->traffic_annotation =
897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26898
899 int rv =
900 trans->Start(request.get(), callback.callback(), NetLogWithSource());
901
902 EXPECT_THAT(callback.GetResult(rv), IsOk());
903 } // Let request info be destroyed.
904
905 trans.reset();
906}
907
mmenkea7da6da2016-09-01 21:56:52908// Response with no status line, and a weird port. Option to allow weird ports
909// enabled.
910TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
911 MockRead data_reads[] = {
912 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
913 };
914
915 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
916 session_deps_.socket_factory->AddSocketDataProvider(&data);
917 session_deps_.http_09_on_non_default_ports_enabled = true;
918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
919
krasinc06a72a2016-12-21 03:42:46920 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58921 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19922 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52923
mmenkea7da6da2016-09-01 21:56:52924 request.method = "GET";
925 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10926 request.traffic_annotation =
927 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
928
mmenkea7da6da2016-09-01 21:56:52929 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20930 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52931 EXPECT_THAT(callback.GetResult(rv), IsOk());
932
933 const HttpResponseInfo* info = trans->GetResponseInfo();
934 ASSERT_TRUE(info->headers);
935 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
936
937 // Don't bother to read the body - that's verified elsewhere, important thing
938 // is that the option to allow HTTP/0.9 on non-default ports is respected.
939}
940
[email protected]231d5a32008-09-13 00:45:27941// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01942TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27943 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35944 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06945 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27946 };
[email protected]31a2bfe2010-02-09 08:03:39947 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
948 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01949 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27950 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
951 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22952 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
953 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27954}
955
956// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01957TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27958 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35959 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06960 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27961 };
[email protected]31a2bfe2010-02-09 08:03:39962 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
963 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01964 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27965 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
966 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22967 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
968 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27969}
970
971// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01972TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27973 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35974 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06975 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27976 };
[email protected]31a2bfe2010-02-09 08:03:39977 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
978 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41979 EXPECT_THAT(out.rv, IsOk());
980 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
981 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
982 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
983 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27984}
985
986// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01987TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27988 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35989 MockRead("\n"),
990 MockRead("\n"),
991 MockRead("Q"),
992 MockRead("J"),
993 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06994 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27995 };
[email protected]31a2bfe2010-02-09 08:03:39996 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
997 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01998 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27999 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
1000 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:221001 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1002 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:271003}
1004
1005// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:011006TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:271007 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351008 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:061009 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:271010 };
[email protected]31a2bfe2010-02-09 08:03:391011 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1012 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411013 EXPECT_THAT(out.rv, IsOk());
1014 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1015 EXPECT_EQ("HTT", out.response_data);
1016 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1017 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521018}
1019
[email protected]f9d44aa2008-09-23 23:57:171020// Simulate a 204 response, lacking a Content-Length header, sent over a
1021// persistent connection. The response should still terminate since a 204
1022// cannot have a response body.
bncd16676a2016-07-20 16:23:011023TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191024 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171025 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351026 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191027 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061028 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171029 };
[email protected]31a2bfe2010-02-09 08:03:391030 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1031 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011032 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171033 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1034 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221035 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1036 int64_t response_size = reads_size - strlen(junk);
1037 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171038}
1039
[email protected]0877e3d2009-10-17 22:29:571040// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011041TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191042 std::string final_chunk = "0\r\n\r\n";
1043 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1044 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571045 MockRead data_reads[] = {
1046 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1047 MockRead("5\r\nHello\r\n"),
1048 MockRead("1\r\n"),
1049 MockRead(" \r\n"),
1050 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191051 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061052 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571053 };
[email protected]31a2bfe2010-02-09 08:03:391054 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1055 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011056 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571057 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1058 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221059 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1060 int64_t response_size = reads_size - extra_data.size();
1061 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571062}
1063
[email protected]9fe44f52010-09-23 18:36:001064// Next tests deal with http://crbug.com/56344.
1065
bncd16676a2016-07-20 16:23:011066TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001067 MultipleContentLengthHeadersNoTransferEncoding) {
1068 MockRead data_reads[] = {
1069 MockRead("HTTP/1.1 200 OK\r\n"),
1070 MockRead("Content-Length: 10\r\n"),
1071 MockRead("Content-Length: 5\r\n\r\n"),
1072 };
1073 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1074 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011075 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001076}
1077
bncd16676a2016-07-20 16:23:011078TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041079 DuplicateContentLengthHeadersNoTransferEncoding) {
1080 MockRead data_reads[] = {
1081 MockRead("HTTP/1.1 200 OK\r\n"),
1082 MockRead("Content-Length: 5\r\n"),
1083 MockRead("Content-Length: 5\r\n\r\n"),
1084 MockRead("Hello"),
1085 };
1086 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1087 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011088 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041089 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1090 EXPECT_EQ("Hello", out.response_data);
1091}
1092
bncd16676a2016-07-20 16:23:011093TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041094 ComplexContentLengthHeadersNoTransferEncoding) {
1095 // More than 2 dupes.
1096 {
1097 MockRead data_reads[] = {
1098 MockRead("HTTP/1.1 200 OK\r\n"),
1099 MockRead("Content-Length: 5\r\n"),
1100 MockRead("Content-Length: 5\r\n"),
1101 MockRead("Content-Length: 5\r\n\r\n"),
1102 MockRead("Hello"),
1103 };
1104 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1105 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011106 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041107 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1108 EXPECT_EQ("Hello", out.response_data);
1109 }
1110 // HTTP/1.0
1111 {
1112 MockRead data_reads[] = {
1113 MockRead("HTTP/1.0 200 OK\r\n"),
1114 MockRead("Content-Length: 5\r\n"),
1115 MockRead("Content-Length: 5\r\n"),
1116 MockRead("Content-Length: 5\r\n\r\n"),
1117 MockRead("Hello"),
1118 };
1119 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1120 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011121 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041122 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1123 EXPECT_EQ("Hello", out.response_data);
1124 }
1125 // 2 dupes and one mismatched.
1126 {
1127 MockRead data_reads[] = {
1128 MockRead("HTTP/1.1 200 OK\r\n"),
1129 MockRead("Content-Length: 10\r\n"),
1130 MockRead("Content-Length: 10\r\n"),
1131 MockRead("Content-Length: 5\r\n\r\n"),
1132 };
1133 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1134 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011135 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041136 }
1137}
1138
bncd16676a2016-07-20 16:23:011139TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001140 MultipleContentLengthHeadersTransferEncoding) {
1141 MockRead data_reads[] = {
1142 MockRead("HTTP/1.1 200 OK\r\n"),
1143 MockRead("Content-Length: 666\r\n"),
1144 MockRead("Content-Length: 1337\r\n"),
1145 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1146 MockRead("5\r\nHello\r\n"),
1147 MockRead("1\r\n"),
1148 MockRead(" \r\n"),
1149 MockRead("5\r\nworld\r\n"),
1150 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061151 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001152 };
1153 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1154 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011155 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001156 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1157 EXPECT_EQ("Hello world", out.response_data);
1158}
1159
[email protected]1628fe92011-10-04 23:04:551160// Next tests deal with http://crbug.com/98895.
1161
1162// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011163TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551164 MockRead data_reads[] = {
1165 MockRead("HTTP/1.1 200 OK\r\n"),
1166 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1167 MockRead("Content-Length: 5\r\n\r\n"),
1168 MockRead("Hello"),
1169 };
1170 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1171 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011172 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551173 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1174 EXPECT_EQ("Hello", out.response_data);
1175}
1176
[email protected]54a9c6e52012-03-21 20:10:591177// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011178TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551179 MockRead data_reads[] = {
1180 MockRead("HTTP/1.1 200 OK\r\n"),
1181 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1182 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1183 MockRead("Content-Length: 5\r\n\r\n"),
1184 MockRead("Hello"),
1185 };
1186 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1187 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011188 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591189 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1190 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551191}
1192
1193// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011194TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551195 MockRead data_reads[] = {
1196 MockRead("HTTP/1.1 200 OK\r\n"),
1197 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1198 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1199 MockRead("Content-Length: 5\r\n\r\n"),
1200 MockRead("Hello"),
1201 };
1202 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1203 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011204 EXPECT_THAT(out.rv,
1205 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551206}
1207
[email protected]54a9c6e52012-03-21 20:10:591208// Checks that two identical Location headers result in no error.
1209// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011210TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551211 MockRead data_reads[] = {
1212 MockRead("HTTP/1.1 302 Redirect\r\n"),
1213 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591214 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551215 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061216 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551217 };
1218
1219 HttpRequestInfo request;
1220 request.method = "GET";
1221 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101222 request.traffic_annotation =
1223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551224
danakj1fd259a02016-04-16 03:17:091225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551227
1228 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071229 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551230
[email protected]49639fa2011-12-20 23:22:411231 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551232
tfarina42834112016-09-22 13:38:201233 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011234 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551235
robpercival214763f2016-07-01 23:27:011236 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551237
bnc691fda62016-08-12 00:43:161238 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521239 ASSERT_TRUE(response);
1240 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551241 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1242 std::string url;
1243 EXPECT_TRUE(response->headers->IsRedirect(&url));
1244 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471245 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551246}
1247
[email protected]1628fe92011-10-04 23:04:551248// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011249TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551250 MockRead data_reads[] = {
1251 MockRead("HTTP/1.1 302 Redirect\r\n"),
1252 MockRead("Location: http://good.com/\r\n"),
1253 MockRead("Location: http://evil.com/\r\n"),
1254 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061255 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551256 };
1257 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1258 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011259 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551260}
1261
[email protected]ef0faf2e72009-03-05 23:27:231262// Do a request using the HEAD method. Verify that we don't try to read the
1263// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011264TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421265 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231266 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231267 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101268 request.traffic_annotation =
1269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231270
danakj1fd259a02016-04-16 03:17:091271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161272 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091273 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161274 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091275 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1276 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271277
[email protected]ef0faf2e72009-03-05 23:27:231278 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131279 MockWrite("HEAD / HTTP/1.1\r\n"
1280 "Host: www.example.org\r\n"
1281 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231282 };
1283 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231284 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1285 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231286
mmenked39192ee2015-12-09 00:57:231287 // No response body because the test stops reading here.
1288 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231289 };
1290
[email protected]31a2bfe2010-02-09 08:03:391291 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1292 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071293 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231294
[email protected]49639fa2011-12-20 23:22:411295 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231296
tfarina42834112016-09-22 13:38:201297 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011298 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231299
1300 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011301 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231302
bnc691fda62016-08-12 00:43:161303 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521304 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231305
1306 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521307 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231308 EXPECT_EQ(1234, response->headers->GetContentLength());
1309 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471310 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091311 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1312 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231313
1314 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101315 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231316 bool has_server_header = response->headers->EnumerateHeader(
1317 &iter, "Server", &server_header);
1318 EXPECT_TRUE(has_server_header);
1319 EXPECT_EQ("Blah", server_header);
1320
1321 // Reading should give EOF right away, since there is no message body
1322 // (despite non-zero content-length).
1323 std::string response_data;
bnc691fda62016-08-12 00:43:161324 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011325 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231326 EXPECT_EQ("", response_data);
1327}
1328
bncd16676a2016-07-20 16:23:011329TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091330 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521331
1332 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351333 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1334 MockRead("hello"),
1335 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1336 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061337 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521338 };
[email protected]31a2bfe2010-02-09 08:03:391339 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071340 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521341
[email protected]0b0bf032010-09-21 18:08:501342 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521343 "hello", "world"
1344 };
1345
1346 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421347 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521348 request.method = "GET";
bncce36dca22015-04-21 22:11:231349 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101350 request.traffic_annotation =
1351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521352
bnc691fda62016-08-12 00:43:161353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271354
[email protected]49639fa2011-12-20 23:22:411355 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521356
tfarina42834112016-09-22 13:38:201357 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521359
1360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011361 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521362
bnc691fda62016-08-12 00:43:161363 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521364 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521365
wezca1070932016-05-26 20:30:521366 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251367 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471368 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521369
1370 std::string response_data;
bnc691fda62016-08-12 00:43:161371 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011372 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251373 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521374 }
1375}
1376
bncd16676a2016-07-20 16:23:011377TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091378 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221379 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191380 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221381 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271382
[email protected]1c773ea12009-04-28 19:58:421383 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521384 request.method = "POST";
1385 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271386 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101387 request.traffic_annotation =
1388 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521389
shivanishab9a143952016-09-19 17:23:411390 // Check the upload progress returned before initialization is correct.
1391 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1392 EXPECT_EQ(0u, progress.size());
1393 EXPECT_EQ(0u, progress.position());
1394
danakj1fd259a02016-04-16 03:17:091395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271397
initial.commit586acc5fe2008-07-26 22:42:521398 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351399 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1400 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1401 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061402 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521403 };
[email protected]31a2bfe2010-02-09 08:03:391404 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071405 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521406
[email protected]49639fa2011-12-20 23:22:411407 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521408
tfarina42834112016-09-22 13:38:201409 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521411
1412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011413 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521414
bnc691fda62016-08-12 00:43:161415 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521416 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521417
wezca1070932016-05-26 20:30:521418 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251419 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521420
1421 std::string response_data;
bnc691fda62016-08-12 00:43:161422 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011423 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251424 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521425}
1426
[email protected]3a2d3662009-03-27 03:49:141427// This test is almost the same as Ignores100 above, but the response contains
1428// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571429// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011430TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421431 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141432 request.method = "GET";
1433 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101434 request.traffic_annotation =
1435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141436
danakj1fd259a02016-04-16 03:17:091437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161438 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271439
[email protected]3a2d3662009-03-27 03:49:141440 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571441 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1442 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141443 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061444 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141445 };
[email protected]31a2bfe2010-02-09 08:03:391446 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071447 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141448
[email protected]49639fa2011-12-20 23:22:411449 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141450
tfarina42834112016-09-22 13:38:201451 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011452 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141453
1454 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011455 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141456
bnc691fda62016-08-12 00:43:161457 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521458 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141459
wezca1070932016-05-26 20:30:521460 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141461 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1462
1463 std::string response_data;
bnc691fda62016-08-12 00:43:161464 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011465 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141466 EXPECT_EQ("hello world", response_data);
1467}
1468
bncd16676a2016-07-20 16:23:011469TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081470 HttpRequestInfo request;
1471 request.method = "POST";
1472 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101473 request.traffic_annotation =
1474 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081475
danakj1fd259a02016-04-16 03:17:091476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081478
1479 MockRead data_reads[] = {
1480 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1481 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381482 };
zmo9528c9f42015-08-04 22:12:081483 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1484 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381485
zmo9528c9f42015-08-04 22:12:081486 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381487
tfarina42834112016-09-22 13:38:201488 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381490
zmo9528c9f42015-08-04 22:12:081491 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011492 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381493
zmo9528c9f42015-08-04 22:12:081494 std::string response_data;
bnc691fda62016-08-12 00:43:161495 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011496 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081497 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381498}
1499
bncd16676a2016-07-20 16:23:011500TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381501 HttpRequestInfo request;
1502 request.method = "POST";
1503 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101504 request.traffic_annotation =
1505 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381506
danakj1fd259a02016-04-16 03:17:091507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271509
[email protected]ee9410e72010-01-07 01:42:381510 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061511 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381512 };
[email protected]31a2bfe2010-02-09 08:03:391513 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071514 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381515
[email protected]49639fa2011-12-20 23:22:411516 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381517
tfarina42834112016-09-22 13:38:201518 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381520
1521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011522 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381523}
1524
[email protected]23e482282013-06-14 16:08:021525void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511526 const MockWrite* write_failure,
1527 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421528 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521529 request.method = "GET";
1530 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101531 request.traffic_annotation =
1532 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521533
vishal.b62985ca92015-04-17 08:45:511534 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071535 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091536 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271537
[email protected]202965992011-12-07 23:04:511538 // Written data for successfully sending both requests.
1539 MockWrite data1_writes[] = {
1540 MockWrite("GET / HTTP/1.1\r\n"
1541 "Host: www.foo.com\r\n"
1542 "Connection: keep-alive\r\n\r\n"),
1543 MockWrite("GET / HTTP/1.1\r\n"
1544 "Host: www.foo.com\r\n"
1545 "Connection: keep-alive\r\n\r\n")
1546 };
1547
1548 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521549 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351550 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1551 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061552 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521553 };
[email protected]202965992011-12-07 23:04:511554
1555 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491556 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511557 data1_writes[1] = *write_failure;
1558 } else {
1559 ASSERT_TRUE(read_failure);
1560 data1_reads[2] = *read_failure;
1561 }
1562
1563 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1564 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071565 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521566
1567 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351568 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1569 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061570 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521571 };
[email protected]31a2bfe2010-02-09 08:03:391572 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071573 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521574
thestig9d3bb0c2015-01-24 00:49:511575 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521576 "hello", "world"
1577 };
1578
mikecironef22f9812016-10-04 03:40:191579 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521580 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411581 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521582
bnc691fda62016-08-12 00:43:161583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521584
tfarina42834112016-09-22 13:38:201585 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521587
1588 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011589 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521590
[email protected]58e32bb2013-01-21 18:23:251591 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161592 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251593 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1594 if (i == 0) {
1595 first_socket_log_id = load_timing_info.socket_log_id;
1596 } else {
1597 // The second request should be using a new socket.
1598 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1599 }
1600
bnc691fda62016-08-12 00:43:161601 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521602 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521603
wezca1070932016-05-26 20:30:521604 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471605 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251606 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521607
1608 std::string response_data;
bnc691fda62016-08-12 00:43:161609 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011610 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251611 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521612 }
1613}
[email protected]3d2a59b2008-09-26 19:44:251614
[email protected]a34f61ee2014-03-18 20:59:491615void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1616 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101617 const MockRead* read_failure,
1618 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491619 HttpRequestInfo request;
1620 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101621 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101622 request.traffic_annotation =
1623 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491624
vishal.b62985ca92015-04-17 08:45:511625 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491626 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491628
[email protected]09356c652014-03-25 15:36:101629 SSLSocketDataProvider ssl1(ASYNC, OK);
1630 SSLSocketDataProvider ssl2(ASYNC, OK);
1631 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361632 ssl1.next_proto = kProtoHTTP2;
1633 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101634 }
1635 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1636 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491637
[email protected]09356c652014-03-25 15:36:101638 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411639 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491640 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411641 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151642 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411643 SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191644 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491645
[email protected]09356c652014-03-25 15:36:101646 // HTTP/1.1 versions of the request and response.
1647 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1648 "Host: www.foo.com\r\n"
1649 "Connection: keep-alive\r\n\r\n";
1650 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1651 const char kHttpData[] = "hello";
1652
1653 std::vector<MockRead> data1_reads;
1654 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491655 if (write_failure) {
1656 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101657 data1_writes.push_back(*write_failure);
1658 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491659 } else {
1660 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101661 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411662 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101663 } else {
1664 data1_writes.push_back(MockWrite(kHttpRequest));
1665 }
1666 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491667 }
1668
[email protected]09356c652014-03-25 15:36:101669 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1670 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491671 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1672
[email protected]09356c652014-03-25 15:36:101673 std::vector<MockRead> data2_reads;
1674 std::vector<MockWrite> data2_writes;
1675
1676 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411677 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101678
bncdf80d44fd2016-07-15 20:27:411679 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1680 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101681 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1682 } else {
1683 data2_writes.push_back(
1684 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1685
1686 data2_reads.push_back(
1687 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1688 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1689 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1690 }
rch8e6c6c42015-05-01 14:05:131691 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1692 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491693 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1694
1695 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591696 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491697 // Wait for the preconnect to complete.
1698 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1699 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101700 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491701
1702 // Make the request.
1703 TestCompletionCallback callback;
1704
bnc691fda62016-08-12 00:43:161705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491706
tfarina42834112016-09-22 13:38:201707 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491709
1710 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011711 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491712
1713 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161714 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101715 TestLoadTimingNotReused(
1716 load_timing_info,
1717 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491718
bnc691fda62016-08-12 00:43:161719 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521720 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491721
wezca1070932016-05-26 20:30:521722 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021723 if (response->was_fetched_via_spdy) {
1724 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1725 } else {
1726 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1727 }
[email protected]a34f61ee2014-03-18 20:59:491728
1729 std::string response_data;
bnc691fda62016-08-12 00:43:161730 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011731 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101732 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491733}
1734
Biljith Jayan45a41722017-08-16 18:43:141735// Test that we do not retry indefinitely when a server sends an error like
1736// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1737// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1738TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1739 HttpRequestInfo request;
1740 request.method = "GET";
1741 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101742 request.traffic_annotation =
1743 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141744
1745 // Check whether we give up after the third try.
1746
1747 // Construct an HTTP2 request and a "Go away" response.
1748 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1749 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291750 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141751 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1752 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1753
1754 // Three go away responses.
1755 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1756 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1757 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1758
1759 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1760 AddSSLSocketData();
1761 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1762 AddSSLSocketData();
1763 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1764 AddSSLSocketData();
1765
1766 TestCompletionCallback callback;
1767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1769
1770 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1772
1773 rv = callback.WaitForResult();
1774 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1775}
1776
1777TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1778 HttpRequestInfo request;
1779 request.method = "GET";
1780 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101781 request.traffic_annotation =
1782 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141783
1784 // Check whether we try atleast thrice before giving up.
1785
1786 // Construct an HTTP2 request and a "Go away" response.
1787 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1788 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291789 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141790 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1791 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1792
1793 // Construct a non error HTTP2 response.
1794 SpdySerializedFrame spdy_response_no_error(
1795 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1796 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1797 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1798 CreateMockRead(spdy_data, 2)};
1799
1800 // Two error responses.
1801 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1802 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1803 // Followed by a success response.
1804 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1805
1806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1807 AddSSLSocketData();
1808 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1809 AddSSLSocketData();
1810 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1811 AddSSLSocketData();
1812
1813 TestCompletionCallback callback;
1814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1816
1817 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1819
1820 rv = callback.WaitForResult();
1821 EXPECT_THAT(rv, IsOk());
1822}
1823
bncd16676a2016-07-20 16:23:011824TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061825 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511826 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1827}
1828
bncd16676a2016-07-20 16:23:011829TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061830 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511831 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251832}
1833
bncd16676a2016-07-20 16:23:011834TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061835 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511836 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251837}
1838
[email protected]d58ceea82014-06-04 10:55:541839// Make sure that on a 408 response (Request Timeout), the request is retried,
1840// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011841TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541842 MockRead read_failure(SYNCHRONOUS,
1843 "HTTP/1.1 408 Request Timeout\r\n"
1844 "Connection: Keep-Alive\r\n"
1845 "Content-Length: 6\r\n\r\n"
1846 "Pickle");
1847 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1848}
1849
bncd16676a2016-07-20 16:23:011850TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491851 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101852 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491853}
1854
bncd16676a2016-07-20 16:23:011855TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491856 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101857 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491858}
1859
bncd16676a2016-07-20 16:23:011860TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491861 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101862 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1863}
1864
bncd16676a2016-07-20 16:23:011865TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101866 MockRead read_failure(ASYNC, OK); // EOF
1867 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1868}
1869
[email protected]d58ceea82014-06-04 10:55:541870// Make sure that on a 408 response (Request Timeout), the request is retried,
1871// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011872TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541873 MockRead read_failure(SYNCHRONOUS,
1874 "HTTP/1.1 408 Request Timeout\r\n"
1875 "Connection: Keep-Alive\r\n"
1876 "Content-Length: 6\r\n\r\n"
1877 "Pickle");
1878 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1879 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1880}
1881
bncd16676a2016-07-20 16:23:011882TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101883 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1884 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1885}
1886
bncd16676a2016-07-20 16:23:011887TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101888 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1889 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1890}
1891
bncd16676a2016-07-20 16:23:011892TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101893 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1894 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1895}
1896
bncd16676a2016-07-20 16:23:011897TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101898 MockRead read_failure(ASYNC, OK); // EOF
1899 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491900}
1901
bncd16676a2016-07-20 16:23:011902TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421903 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251904 request.method = "GET";
bncce36dca22015-04-21 22:11:231905 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101906 request.traffic_annotation =
1907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251908
danakj1fd259a02016-04-16 03:17:091909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161910 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271911
[email protected]3d2a59b2008-09-26 19:44:251912 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061913 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351914 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1915 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061916 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251917 };
[email protected]31a2bfe2010-02-09 08:03:391918 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071919 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251920
[email protected]49639fa2011-12-20 23:22:411921 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251922
tfarina42834112016-09-22 13:38:201923 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011924 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251925
1926 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011927 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591928
1929 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161930 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591931 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251932}
1933
1934// What do various browsers do when the server closes a non-keepalive
1935// connection without sending any response header or body?
1936//
1937// IE7: error page
1938// Safari 3.1.2 (Windows): error page
1939// Firefox 3.0.1: blank page
1940// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421941// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1942// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011943TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251944 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061945 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351946 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1947 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061948 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251949 };
[email protected]31a2bfe2010-02-09 08:03:391950 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1951 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011952 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251953}
[email protected]1826a402014-01-08 15:40:481954
[email protected]7a5378b2012-11-04 03:25:171955// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1956// tests. There was a bug causing HttpNetworkTransaction to hang in the
1957// destructor in such situations.
1958// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011959TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171960 HttpRequestInfo request;
1961 request.method = "GET";
bncce36dca22015-04-21 22:11:231962 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101963 request.traffic_annotation =
1964 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171965
danakj1fd259a02016-04-16 03:17:091966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581967 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191968 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171969
1970 MockRead data_reads[] = {
1971 MockRead("HTTP/1.0 200 OK\r\n"),
1972 MockRead("Connection: keep-alive\r\n"),
1973 MockRead("Content-Length: 100\r\n\r\n"),
1974 MockRead("hello"),
1975 MockRead(SYNCHRONOUS, 0),
1976 };
1977 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071978 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171979
1980 TestCompletionCallback callback;
1981
tfarina42834112016-09-22 13:38:201982 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171984
1985 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011986 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171987
1988 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501989 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171990 if (rv == ERR_IO_PENDING)
1991 rv = callback.WaitForResult();
1992 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501993 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011994 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171995
1996 trans.reset();
fdoray92e35a72016-06-10 15:54:551997 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171998 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1999}
2000
bncd16676a2016-07-20 16:23:012001TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172002 HttpRequestInfo request;
2003 request.method = "GET";
bncce36dca22015-04-21 22:11:232004 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102005 request.traffic_annotation =
2006 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172007
danakj1fd259a02016-04-16 03:17:092008 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582009 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192010 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172011
2012 MockRead data_reads[] = {
2013 MockRead("HTTP/1.0 200 OK\r\n"),
2014 MockRead("Connection: keep-alive\r\n"),
2015 MockRead("Content-Length: 100\r\n\r\n"),
2016 MockRead(SYNCHRONOUS, 0),
2017 };
2018 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072019 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172020
2021 TestCompletionCallback callback;
2022
tfarina42834112016-09-22 13:38:202023 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172025
2026 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012027 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172028
2029 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:502030 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172031 if (rv == ERR_IO_PENDING)
2032 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012033 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172034
2035 trans.reset();
fdoray92e35a72016-06-10 15:54:552036 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172037 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2038}
2039
[email protected]0b0bf032010-09-21 18:08:502040// Test that we correctly reuse a keep-alive connection after not explicitly
2041// reading the body.
bncd16676a2016-07-20 16:23:012042TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132043 HttpRequestInfo request;
2044 request.method = "GET";
2045 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102046 request.traffic_annotation =
2047 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132048
vishal.b62985ca92015-04-17 08:45:512049 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072050 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272052
mmenkecc2298e2015-12-07 18:20:182053 const char* request_data =
2054 "GET / HTTP/1.1\r\n"
2055 "Host: www.foo.com\r\n"
2056 "Connection: keep-alive\r\n\r\n";
2057 MockWrite data_writes[] = {
2058 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2059 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2060 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2061 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2062 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2063 };
2064
[email protected]0b0bf032010-09-21 18:08:502065 // Note that because all these reads happen in the same
2066 // StaticSocketDataProvider, it shows that the same socket is being reused for
2067 // all transactions.
mmenkecc2298e2015-12-07 18:20:182068 MockRead data_reads[] = {
2069 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2070 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2071 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2072 MockRead(ASYNC, 7,
2073 "HTTP/1.1 302 Found\r\n"
2074 "Content-Length: 0\r\n\r\n"),
2075 MockRead(ASYNC, 9,
2076 "HTTP/1.1 302 Found\r\n"
2077 "Content-Length: 5\r\n\r\n"
2078 "hello"),
2079 MockRead(ASYNC, 11,
2080 "HTTP/1.1 301 Moved Permanently\r\n"
2081 "Content-Length: 0\r\n\r\n"),
2082 MockRead(ASYNC, 13,
2083 "HTTP/1.1 301 Moved Permanently\r\n"
2084 "Content-Length: 5\r\n\r\n"
2085 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132086
mmenkecc2298e2015-12-07 18:20:182087 // In the next two rounds, IsConnectedAndIdle returns false, due to
2088 // the set_busy_before_sync_reads(true) call, while the
2089 // HttpNetworkTransaction is being shut down, but the socket is still
2090 // reuseable. See http://crbug.com/544255.
2091 MockRead(ASYNC, 15,
2092 "HTTP/1.1 200 Hunky-Dory\r\n"
2093 "Content-Length: 5\r\n\r\n"),
2094 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132095
mmenkecc2298e2015-12-07 18:20:182096 MockRead(ASYNC, 18,
2097 "HTTP/1.1 200 Hunky-Dory\r\n"
2098 "Content-Length: 5\r\n\r\n"
2099 "he"),
2100 MockRead(SYNCHRONOUS, 19, "llo"),
2101
2102 // The body of the final request is actually read.
2103 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2104 MockRead(ASYNC, 22, "hello"),
2105 };
2106 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2107 arraysize(data_writes));
2108 data.set_busy_before_sync_reads(true);
2109 session_deps_.socket_factory->AddSocketDataProvider(&data);
2110
2111 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502112 std::string response_lines[kNumUnreadBodies];
2113
mikecironef22f9812016-10-04 03:40:192114 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182115 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412116 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132117
Jeremy Roman0579ed62017-08-29 15:56:192118 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582119 session.get());
[email protected]fc31d6a42010-06-24 18:05:132120
tfarina42834112016-09-22 13:38:202121 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012122 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132123
[email protected]58e32bb2013-01-21 18:23:252124 LoadTimingInfo load_timing_info;
2125 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2126 if (i == 0) {
2127 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2128 first_socket_log_id = load_timing_info.socket_log_id;
2129 } else {
2130 TestLoadTimingReused(load_timing_info);
2131 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2132 }
2133
[email protected]fc31d6a42010-06-24 18:05:132134 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182135 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132136
mmenkecc2298e2015-12-07 18:20:182137 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502138 response_lines[i] = response->headers->GetStatusLine();
2139
mmenkecc2298e2015-12-07 18:20:182140 // Delete the transaction without reading the response bodies. Then spin
2141 // the message loop, so the response bodies are drained.
2142 trans.reset();
2143 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132144 }
[email protected]0b0bf032010-09-21 18:08:502145
2146 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182147 "HTTP/1.1 204 No Content",
2148 "HTTP/1.1 205 Reset Content",
2149 "HTTP/1.1 304 Not Modified",
2150 "HTTP/1.1 302 Found",
2151 "HTTP/1.1 302 Found",
2152 "HTTP/1.1 301 Moved Permanently",
2153 "HTTP/1.1 301 Moved Permanently",
2154 "HTTP/1.1 200 Hunky-Dory",
2155 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502156 };
2157
mostynb91e0da982015-01-20 19:17:272158 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2159 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502160
2161 for (int i = 0; i < kNumUnreadBodies; ++i)
2162 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2163
[email protected]49639fa2011-12-20 23:22:412164 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202166 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012167 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162168 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182169 ASSERT_TRUE(response);
2170 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502171 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2172 std::string response_data;
bnc691fda62016-08-12 00:43:162173 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012174 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502175 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132176}
2177
mmenke5f94fda2016-06-02 20:54:132178// Sockets that receive extra data after a response is complete should not be
2179// reused.
bncd16676a2016-07-20 16:23:012180TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132181 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2182 MockWrite data_writes1[] = {
2183 MockWrite("HEAD / HTTP/1.1\r\n"
2184 "Host: www.borked.com\r\n"
2185 "Connection: keep-alive\r\n\r\n"),
2186 };
2187
2188 MockRead data_reads1[] = {
2189 MockRead("HTTP/1.1 200 OK\r\n"
2190 "Connection: keep-alive\r\n"
2191 "Content-Length: 22\r\n\r\n"
2192 "This server is borked."),
2193 };
2194
2195 MockWrite data_writes2[] = {
2196 MockWrite("GET /foo HTTP/1.1\r\n"
2197 "Host: www.borked.com\r\n"
2198 "Connection: keep-alive\r\n\r\n"),
2199 };
2200
2201 MockRead data_reads2[] = {
2202 MockRead("HTTP/1.1 200 OK\r\n"
2203 "Content-Length: 3\r\n\r\n"
2204 "foo"),
2205 };
2206 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2207 data_writes1, arraysize(data_writes1));
2208 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2209 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2210 data_writes2, arraysize(data_writes2));
2211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2212
2213 TestCompletionCallback callback;
2214 HttpRequestInfo request1;
2215 request1.method = "HEAD";
2216 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102217 request1.traffic_annotation =
2218 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132219
bnc87dcefc2017-05-25 12:47:582220 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192221 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202222 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012223 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132224
2225 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2226 ASSERT_TRUE(response1);
2227 ASSERT_TRUE(response1->headers);
2228 EXPECT_EQ(200, response1->headers->response_code());
2229 EXPECT_TRUE(response1->headers->IsKeepAlive());
2230
2231 std::string response_data1;
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132233 EXPECT_EQ("", response_data1);
2234 // Deleting the transaction attempts to release the socket back into the
2235 // socket pool.
2236 trans1.reset();
2237
2238 HttpRequestInfo request2;
2239 request2.method = "GET";
2240 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102241 request2.traffic_annotation =
2242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132243
bnc87dcefc2017-05-25 12:47:582244 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192245 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202246 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012247 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132248
2249 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2250 ASSERT_TRUE(response2);
2251 ASSERT_TRUE(response2->headers);
2252 EXPECT_EQ(200, response2->headers->response_code());
2253
2254 std::string response_data2;
robpercival214763f2016-07-01 23:27:012255 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132256 EXPECT_EQ("foo", response_data2);
2257}
2258
bncd16676a2016-07-20 16:23:012259TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2261 MockWrite data_writes1[] = {
2262 MockWrite("GET / HTTP/1.1\r\n"
2263 "Host: www.borked.com\r\n"
2264 "Connection: keep-alive\r\n\r\n"),
2265 };
2266
2267 MockRead data_reads1[] = {
2268 MockRead("HTTP/1.1 200 OK\r\n"
2269 "Connection: keep-alive\r\n"
2270 "Content-Length: 22\r\n\r\n"
2271 "This server is borked."
2272 "Bonus data!"),
2273 };
2274
2275 MockWrite data_writes2[] = {
2276 MockWrite("GET /foo HTTP/1.1\r\n"
2277 "Host: www.borked.com\r\n"
2278 "Connection: keep-alive\r\n\r\n"),
2279 };
2280
2281 MockRead data_reads2[] = {
2282 MockRead("HTTP/1.1 200 OK\r\n"
2283 "Content-Length: 3\r\n\r\n"
2284 "foo"),
2285 };
2286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2287 data_writes1, arraysize(data_writes1));
2288 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2289 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2290 data_writes2, arraysize(data_writes2));
2291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2292
2293 TestCompletionCallback callback;
2294 HttpRequestInfo request1;
2295 request1.method = "GET";
2296 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102297 request1.traffic_annotation =
2298 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132299
bnc87dcefc2017-05-25 12:47:582300 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192301 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202302 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012303 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132304
2305 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2306 ASSERT_TRUE(response1);
2307 ASSERT_TRUE(response1->headers);
2308 EXPECT_EQ(200, response1->headers->response_code());
2309 EXPECT_TRUE(response1->headers->IsKeepAlive());
2310
2311 std::string response_data1;
robpercival214763f2016-07-01 23:27:012312 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132313 EXPECT_EQ("This server is borked.", response_data1);
2314 // Deleting the transaction attempts to release the socket back into the
2315 // socket pool.
2316 trans1.reset();
2317
2318 HttpRequestInfo request2;
2319 request2.method = "GET";
2320 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102321 request2.traffic_annotation =
2322 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132323
bnc87dcefc2017-05-25 12:47:582324 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192325 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202326 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012327 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132328
2329 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2330 ASSERT_TRUE(response2);
2331 ASSERT_TRUE(response2->headers);
2332 EXPECT_EQ(200, response2->headers->response_code());
2333
2334 std::string response_data2;
robpercival214763f2016-07-01 23:27:012335 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132336 EXPECT_EQ("foo", response_data2);
2337}
2338
bncd16676a2016-07-20 16:23:012339TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2341 MockWrite data_writes1[] = {
2342 MockWrite("GET / HTTP/1.1\r\n"
2343 "Host: www.borked.com\r\n"
2344 "Connection: keep-alive\r\n\r\n"),
2345 };
2346
2347 MockRead data_reads1[] = {
2348 MockRead("HTTP/1.1 200 OK\r\n"
2349 "Connection: keep-alive\r\n"
2350 "Transfer-Encoding: chunked\r\n\r\n"),
2351 MockRead("16\r\nThis server is borked.\r\n"),
2352 MockRead("0\r\n\r\nBonus data!"),
2353 };
2354
2355 MockWrite data_writes2[] = {
2356 MockWrite("GET /foo HTTP/1.1\r\n"
2357 "Host: www.borked.com\r\n"
2358 "Connection: keep-alive\r\n\r\n"),
2359 };
2360
2361 MockRead data_reads2[] = {
2362 MockRead("HTTP/1.1 200 OK\r\n"
2363 "Content-Length: 3\r\n\r\n"
2364 "foo"),
2365 };
2366 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2367 data_writes1, arraysize(data_writes1));
2368 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2369 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2370 data_writes2, arraysize(data_writes2));
2371 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2372
2373 TestCompletionCallback callback;
2374 HttpRequestInfo request1;
2375 request1.method = "GET";
2376 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102377 request1.traffic_annotation =
2378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132379
bnc87dcefc2017-05-25 12:47:582380 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192381 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202382 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012383 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132384
2385 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2386 ASSERT_TRUE(response1);
2387 ASSERT_TRUE(response1->headers);
2388 EXPECT_EQ(200, response1->headers->response_code());
2389 EXPECT_TRUE(response1->headers->IsKeepAlive());
2390
2391 std::string response_data1;
robpercival214763f2016-07-01 23:27:012392 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132393 EXPECT_EQ("This server is borked.", response_data1);
2394 // Deleting the transaction attempts to release the socket back into the
2395 // socket pool.
2396 trans1.reset();
2397
2398 HttpRequestInfo request2;
2399 request2.method = "GET";
2400 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102401 request2.traffic_annotation =
2402 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132403
bnc87dcefc2017-05-25 12:47:582404 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192405 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202406 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012407 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132408
2409 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2410 ASSERT_TRUE(response2);
2411 ASSERT_TRUE(response2->headers);
2412 EXPECT_EQ(200, response2->headers->response_code());
2413
2414 std::string response_data2;
robpercival214763f2016-07-01 23:27:012415 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132416 EXPECT_EQ("foo", response_data2);
2417}
2418
2419// This is a little different from the others - it tests the case that the
2420// HttpStreamParser doesn't know if there's extra data on a socket or not when
2421// the HttpNetworkTransaction is torn down, because the response body hasn't
2422// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012423TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2425 MockWrite data_writes1[] = {
2426 MockWrite("GET / HTTP/1.1\r\n"
2427 "Host: www.borked.com\r\n"
2428 "Connection: keep-alive\r\n\r\n"),
2429 };
2430
2431 MockRead data_reads1[] = {
2432 MockRead("HTTP/1.1 200 OK\r\n"
2433 "Connection: keep-alive\r\n"
2434 "Transfer-Encoding: chunked\r\n\r\n"),
2435 MockRead("16\r\nThis server is borked.\r\n"),
2436 MockRead("0\r\n\r\nBonus data!"),
2437 };
2438 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2439 data_writes1, arraysize(data_writes1));
2440 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2441
2442 TestCompletionCallback callback;
2443 HttpRequestInfo request1;
2444 request1.method = "GET";
2445 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102446 request1.traffic_annotation =
2447 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132448
bnc87dcefc2017-05-25 12:47:582449 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192450 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582451 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012452 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132453
bnc87dcefc2017-05-25 12:47:582454 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132455 ASSERT_TRUE(response1);
2456 ASSERT_TRUE(response1->headers);
2457 EXPECT_EQ(200, response1->headers->response_code());
2458 EXPECT_TRUE(response1->headers->IsKeepAlive());
2459
2460 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2461 // response body.
bnc87dcefc2017-05-25 12:47:582462 trans.reset();
mmenke5f94fda2016-06-02 20:54:132463
2464 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2465 // socket can't be reused, rather than returning it to the socket pool.
2466 base::RunLoop().RunUntilIdle();
2467
2468 // There should be no idle sockets in the pool.
2469 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2470}
2471
[email protected]038e9a32008-10-08 22:40:162472// Test the request-challenge-retry sequence for basic auth.
2473// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012474TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422475 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162476 request.method = "GET";
bncce36dca22015-04-21 22:11:232477 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102478 request.traffic_annotation =
2479 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162480
vishal.b62985ca92015-04-17 08:45:512481 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072482 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092483 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162484 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272485
[email protected]f9ee6b52008-11-08 06:46:232486 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232487 MockWrite(
2488 "GET / HTTP/1.1\r\n"
2489 "Host: www.example.org\r\n"
2490 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232491 };
2492
[email protected]038e9a32008-10-08 22:40:162493 MockRead data_reads1[] = {
2494 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2495 // Give a couple authenticate options (only the middle one is actually
2496 // supported).
[email protected]22927ad2009-09-21 19:56:192497 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162498 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2499 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2500 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2501 // Large content-length -- won't matter, as connection will be reset.
2502 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062503 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162504 };
2505
2506 // After calling trans->RestartWithAuth(), this is the request we should
2507 // be issuing -- the final header line contains the credentials.
2508 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232509 MockWrite(
2510 "GET / HTTP/1.1\r\n"
2511 "Host: www.example.org\r\n"
2512 "Connection: keep-alive\r\n"
2513 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162514 };
2515
2516 // Lastly, the server responds with the actual content.
2517 MockRead data_reads2[] = {
2518 MockRead("HTTP/1.0 200 OK\r\n"),
2519 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2520 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062521 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162522 };
2523
[email protected]31a2bfe2010-02-09 08:03:392524 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2525 data_writes1, arraysize(data_writes1));
2526 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2527 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072528 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2529 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162530
[email protected]49639fa2011-12-20 23:22:412531 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162532
tfarina42834112016-09-22 13:38:202533 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162535
2536 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012537 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162538
[email protected]58e32bb2013-01-21 18:23:252539 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162540 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252541 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2542
sclittlefb249892015-09-10 21:33:222543 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162544 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222545 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162546 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192547
bnc691fda62016-08-12 00:43:162548 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522549 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042550 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162551
[email protected]49639fa2011-12-20 23:22:412552 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162553
bnc691fda62016-08-12 00:43:162554 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162556
2557 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012558 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162559
[email protected]58e32bb2013-01-21 18:23:252560 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162561 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252562 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2563 // The load timing after restart should have a new socket ID, and times after
2564 // those of the first load timing.
2565 EXPECT_LE(load_timing_info1.receive_headers_end,
2566 load_timing_info2.connect_timing.connect_start);
2567 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2568
sclittlefb249892015-09-10 21:33:222569 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162570 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222571 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162572 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192573
bnc691fda62016-08-12 00:43:162574 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522575 ASSERT_TRUE(response);
2576 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162577 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162578}
2579
ttuttled9dbc652015-09-29 20:00:592580// Test the request-challenge-retry sequence for basic auth.
2581// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012582TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592583 HttpRequestInfo request;
2584 request.method = "GET";
2585 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102586 request.traffic_annotation =
2587 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592588
2589 TestNetLog log;
2590 MockHostResolver* resolver = new MockHostResolver();
2591 session_deps_.net_log = &log;
2592 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092593 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592595
2596 resolver->rules()->ClearRules();
2597 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2598
2599 MockWrite data_writes1[] = {
2600 MockWrite("GET / HTTP/1.1\r\n"
2601 "Host: www.example.org\r\n"
2602 "Connection: keep-alive\r\n\r\n"),
2603 };
2604
2605 MockRead data_reads1[] = {
2606 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2607 // Give a couple authenticate options (only the middle one is actually
2608 // supported).
2609 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2610 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2611 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2612 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2613 // Large content-length -- won't matter, as connection will be reset.
2614 MockRead("Content-Length: 10000\r\n\r\n"),
2615 MockRead(SYNCHRONOUS, ERR_FAILED),
2616 };
2617
2618 // After calling trans->RestartWithAuth(), this is the request we should
2619 // be issuing -- the final header line contains the credentials.
2620 MockWrite data_writes2[] = {
2621 MockWrite("GET / HTTP/1.1\r\n"
2622 "Host: www.example.org\r\n"
2623 "Connection: keep-alive\r\n"
2624 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2625 };
2626
2627 // Lastly, the server responds with the actual content.
2628 MockRead data_reads2[] = {
2629 MockRead("HTTP/1.0 200 OK\r\n"),
2630 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2631 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2632 };
2633
2634 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2635 data_writes1, arraysize(data_writes1));
2636 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2637 data_writes2, arraysize(data_writes2));
2638 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2639 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2640
2641 TestCompletionCallback callback1;
2642
bnc691fda62016-08-12 00:43:162643 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202644 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592645
2646 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162647 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592648 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2649
2650 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162651 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592652 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162653 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592654
bnc691fda62016-08-12 00:43:162655 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592656 ASSERT_TRUE(response);
2657 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2658
2659 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162660 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592661 ASSERT_FALSE(endpoint.address().empty());
2662 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2663
2664 resolver->rules()->ClearRules();
2665 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2666
2667 TestCompletionCallback callback2;
2668
bnc691fda62016-08-12 00:43:162669 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592670 AuthCredentials(kFoo, kBar), callback2.callback())));
2671
2672 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162673 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592674 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2675 // The load timing after restart should have a new socket ID, and times after
2676 // those of the first load timing.
2677 EXPECT_LE(load_timing_info1.receive_headers_end,
2678 load_timing_info2.connect_timing.connect_start);
2679 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2680
2681 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162682 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592683 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162684 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592685
bnc691fda62016-08-12 00:43:162686 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592687 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522688 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592689 EXPECT_EQ(100, response->headers->GetContentLength());
2690
bnc691fda62016-08-12 00:43:162691 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592692 ASSERT_FALSE(endpoint.address().empty());
2693 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2694}
2695
bncd16676a2016-07-20 16:23:012696TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462697 HttpRequestInfo request;
2698 request.method = "GET";
bncce36dca22015-04-21 22:11:232699 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292700 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102701 request.traffic_annotation =
2702 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462703
danakj1fd259a02016-04-16 03:17:092704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272706
[email protected]861fcd52009-08-26 02:33:462707 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232708 MockWrite(
2709 "GET / HTTP/1.1\r\n"
2710 "Host: www.example.org\r\n"
2711 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462712 };
2713
2714 MockRead data_reads[] = {
2715 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2716 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2717 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2718 // Large content-length -- won't matter, as connection will be reset.
2719 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062720 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462721 };
2722
[email protected]31a2bfe2010-02-09 08:03:392723 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2724 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072725 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412726 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462727
tfarina42834112016-09-22 13:38:202728 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462730
2731 rv = callback.WaitForResult();
2732 EXPECT_EQ(0, rv);
2733
sclittlefb249892015-09-10 21:33:222734 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162735 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222736 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162737 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192738
bnc691fda62016-08-12 00:43:162739 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522740 ASSERT_TRUE(response);
2741 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462742}
2743
[email protected]2d2697f92009-02-18 21:00:322744// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2745// connection.
bncd16676a2016-07-20 16:23:012746TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182747 // On the second pass, the body read of the auth challenge is synchronous, so
2748 // IsConnectedAndIdle returns false. The socket should still be drained and
2749 // reused. See http://crbug.com/544255.
2750 for (int i = 0; i < 2; ++i) {
2751 HttpRequestInfo request;
2752 request.method = "GET";
2753 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102754 request.traffic_annotation =
2755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322756
mmenkecc2298e2015-12-07 18:20:182757 TestNetLog log;
2758 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272760
mmenkecc2298e2015-12-07 18:20:182761 MockWrite data_writes[] = {
2762 MockWrite(ASYNC, 0,
2763 "GET / HTTP/1.1\r\n"
2764 "Host: www.example.org\r\n"
2765 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322766
bnc691fda62016-08-12 00:43:162767 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182768 // be issuing -- the final header line contains the credentials.
2769 MockWrite(ASYNC, 6,
2770 "GET / HTTP/1.1\r\n"
2771 "Host: www.example.org\r\n"
2772 "Connection: keep-alive\r\n"
2773 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2774 };
[email protected]2d2697f92009-02-18 21:00:322775
mmenkecc2298e2015-12-07 18:20:182776 MockRead data_reads[] = {
2777 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2778 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2779 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2780 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2781 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322782
mmenkecc2298e2015-12-07 18:20:182783 // Lastly, the server responds with the actual content.
2784 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2785 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2786 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2787 MockRead(ASYNC, 10, "Hello"),
2788 };
[email protected]2d2697f92009-02-18 21:00:322789
mmenkecc2298e2015-12-07 18:20:182790 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2791 arraysize(data_writes));
2792 data.set_busy_before_sync_reads(true);
2793 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462794
mmenkecc2298e2015-12-07 18:20:182795 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322796
bnc691fda62016-08-12 00:43:162797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202798 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012799 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322800
mmenkecc2298e2015-12-07 18:20:182801 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162802 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182803 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322804
bnc691fda62016-08-12 00:43:162805 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182806 ASSERT_TRUE(response);
2807 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322808
mmenkecc2298e2015-12-07 18:20:182809 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252810
bnc691fda62016-08-12 00:43:162811 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2812 callback2.callback());
robpercival214763f2016-07-01 23:27:012813 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322814
mmenkecc2298e2015-12-07 18:20:182815 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162816 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182817 TestLoadTimingReused(load_timing_info2);
2818 // The load timing after restart should have the same socket ID, and times
2819 // those of the first load timing.
2820 EXPECT_LE(load_timing_info1.receive_headers_end,
2821 load_timing_info2.send_start);
2822 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322823
bnc691fda62016-08-12 00:43:162824 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182825 ASSERT_TRUE(response);
2826 EXPECT_FALSE(response->auth_challenge);
2827 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322828
mmenkecc2298e2015-12-07 18:20:182829 std::string response_data;
bnc691fda62016-08-12 00:43:162830 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322831
mmenkecc2298e2015-12-07 18:20:182832 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162833 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182834 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162835 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182836 }
[email protected]2d2697f92009-02-18 21:00:322837}
2838
2839// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2840// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012841TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422842 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322843 request.method = "GET";
bncce36dca22015-04-21 22:11:232844 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102845 request.traffic_annotation =
2846 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322847
danakj1fd259a02016-04-16 03:17:092848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272849
[email protected]2d2697f92009-02-18 21:00:322850 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162851 MockWrite("GET / HTTP/1.1\r\n"
2852 "Host: www.example.org\r\n"
2853 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322854
bnc691fda62016-08-12 00:43:162855 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232856 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162857 MockWrite("GET / HTTP/1.1\r\n"
2858 "Host: www.example.org\r\n"
2859 "Connection: keep-alive\r\n"
2860 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322861 };
2862
[email protected]2d2697f92009-02-18 21:00:322863 MockRead data_reads1[] = {
2864 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2865 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312866 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322867
2868 // Lastly, the server responds with the actual content.
2869 MockRead("HTTP/1.1 200 OK\r\n"),
2870 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502871 MockRead("Content-Length: 5\r\n\r\n"),
2872 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322873 };
2874
[email protected]2d0a4f92011-05-05 16:38:462875 // An incorrect reconnect would cause this to be read.
2876 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062877 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462878 };
2879
[email protected]31a2bfe2010-02-09 08:03:392880 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2881 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462882 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2883 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072884 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2885 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322886
[email protected]49639fa2011-12-20 23:22:412887 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322888
bnc691fda62016-08-12 00:43:162889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202890 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322892
2893 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012894 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322895
bnc691fda62016-08-12 00:43:162896 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522897 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042898 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322899
[email protected]49639fa2011-12-20 23:22:412900 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322901
bnc691fda62016-08-12 00:43:162902 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322904
2905 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012906 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322907
bnc691fda62016-08-12 00:43:162908 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522909 ASSERT_TRUE(response);
2910 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502911 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322912}
2913
2914// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2915// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012916TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422917 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322918 request.method = "GET";
bncce36dca22015-04-21 22:11:232919 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102920 request.traffic_annotation =
2921 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322922
danakj1fd259a02016-04-16 03:17:092923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272924
[email protected]2d2697f92009-02-18 21:00:322925 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162926 MockWrite("GET / HTTP/1.1\r\n"
2927 "Host: www.example.org\r\n"
2928 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322929
bnc691fda62016-08-12 00:43:162930 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232931 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162932 MockWrite("GET / HTTP/1.1\r\n"
2933 "Host: www.example.org\r\n"
2934 "Connection: keep-alive\r\n"
2935 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322936 };
2937
2938 // Respond with 5 kb of response body.
2939 std::string large_body_string("Unauthorized");
2940 large_body_string.append(5 * 1024, ' ');
2941 large_body_string.append("\r\n");
2942
2943 MockRead data_reads1[] = {
2944 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2945 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2946 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2947 // 5134 = 12 + 5 * 1024 + 2
2948 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062949 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322950
2951 // Lastly, the server responds with the actual content.
2952 MockRead("HTTP/1.1 200 OK\r\n"),
2953 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502954 MockRead("Content-Length: 5\r\n\r\n"),
2955 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322956 };
2957
[email protected]2d0a4f92011-05-05 16:38:462958 // An incorrect reconnect would cause this to be read.
2959 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062960 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462961 };
2962
[email protected]31a2bfe2010-02-09 08:03:392963 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2964 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462965 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2966 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072967 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2968 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322969
[email protected]49639fa2011-12-20 23:22:412970 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322971
bnc691fda62016-08-12 00:43:162972 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202973 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012974 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322975
2976 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012977 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322978
bnc691fda62016-08-12 00:43:162979 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522980 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042981 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322982
[email protected]49639fa2011-12-20 23:22:412983 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322984
bnc691fda62016-08-12 00:43:162985 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322987
2988 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012989 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322990
bnc691fda62016-08-12 00:43:162991 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522992 ASSERT_TRUE(response);
2993 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502994 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322995}
2996
2997// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312998// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012999TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313000 HttpRequestInfo request;
3001 request.method = "GET";
bncce36dca22015-04-21 22:11:233002 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103003 request.traffic_annotation =
3004 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313005
danakj1fd259a02016-04-16 03:17:093006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273007
[email protected]11203f012009-11-12 23:02:313008 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233009 MockWrite(
3010 "GET / HTTP/1.1\r\n"
3011 "Host: www.example.org\r\n"
3012 "Connection: keep-alive\r\n\r\n"),
3013 // This simulates the seemingly successful write to a closed connection
3014 // if the bug is not fixed.
3015 MockWrite(
3016 "GET / HTTP/1.1\r\n"
3017 "Host: www.example.org\r\n"
3018 "Connection: keep-alive\r\n"
3019 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313020 };
3021
3022 MockRead data_reads1[] = {
3023 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3024 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3025 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3026 MockRead("Content-Length: 14\r\n\r\n"),
3027 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063028 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313029 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063030 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313031 };
3032
bnc691fda62016-08-12 00:43:163033 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313034 // be issuing -- the final header line contains the credentials.
3035 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233036 MockWrite(
3037 "GET / HTTP/1.1\r\n"
3038 "Host: www.example.org\r\n"
3039 "Connection: keep-alive\r\n"
3040 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313041 };
3042
3043 // Lastly, the server responds with the actual content.
3044 MockRead data_reads2[] = {
3045 MockRead("HTTP/1.1 200 OK\r\n"),
3046 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503047 MockRead("Content-Length: 5\r\n\r\n"),
3048 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313049 };
3050
[email protected]31a2bfe2010-02-09 08:03:393051 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3052 data_writes1, arraysize(data_writes1));
3053 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3054 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073055 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3056 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313057
[email protected]49639fa2011-12-20 23:22:413058 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313059
bnc691fda62016-08-12 00:43:163060 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203061 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313063
3064 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013065 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313066
bnc691fda62016-08-12 00:43:163067 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523068 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043069 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313070
[email protected]49639fa2011-12-20 23:22:413071 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313072
bnc691fda62016-08-12 00:43:163073 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313075
3076 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013077 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313078
bnc691fda62016-08-12 00:43:163079 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523080 ASSERT_TRUE(response);
3081 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503082 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313083}
3084
[email protected]394816e92010-08-03 07:38:593085// Test the request-challenge-retry sequence for basic auth, over a connection
3086// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013087TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013088 HttpRequestInfo request;
3089 request.method = "GET";
bncce36dca22015-04-21 22:11:233090 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013091 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293092 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103093 request.traffic_annotation =
3094 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013095
3096 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593097 session_deps_.proxy_resolution_service =
3098 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
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 Halavatib5e433e2018-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 =
3225 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513226 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073227 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273229
[email protected]394816e92010-08-03 07:38:593230 // Since we have proxy, should try to establish tunnel.
3231 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543232 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173233 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543234 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113235 };
3236
mmenkee71e15332015-10-07 16:39:543237 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083238 // connection.
3239 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543240 // No credentials.
3241 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3242 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3243 MockRead("Proxy-Connection: close\r\n\r\n"),
3244 };
mmenkee0b5c882015-08-26 20:29:113245
mmenkee71e15332015-10-07 16:39:543246 MockWrite data_writes2[] = {
3247 // After calling trans->RestartWithAuth(), this is the request we should
3248 // be issuing -- the final header line contains the credentials.
3249 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173250 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543251 "Proxy-Connection: keep-alive\r\n"
3252 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083253
mmenkee71e15332015-10-07 16:39:543254 MockWrite("GET / HTTP/1.1\r\n"
3255 "Host: www.example.org\r\n"
3256 "Connection: keep-alive\r\n\r\n"),
3257 };
3258
3259 MockRead data_reads2[] = {
3260 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3261
3262 MockRead("HTTP/1.1 200 OK\r\n"),
3263 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3264 MockRead("Content-Length: 5\r\n\r\n"),
3265 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593266 };
3267
3268 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3269 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073270 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543271 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3272 data_writes2, arraysize(data_writes2));
3273 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063274 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593276
[email protected]49639fa2011-12-20 23:22:413277 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593278
bnc87dcefc2017-05-25 12:47:583279 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193280 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503281
[email protected]49639fa2011-12-20 23:22:413282 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593284
3285 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013286 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463287 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403288 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593289 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003290 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3291 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593292 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403293 entries, pos,
mikecirone8b85c432016-09-08 19:11:003294 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3295 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593296
3297 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523298 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013299 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523300 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593301 EXPECT_EQ(407, response->headers->response_code());
3302 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043303 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593304
[email protected]029c83b62013-01-24 05:28:203305 LoadTimingInfo load_timing_info;
3306 // CONNECT requests and responses are handled at the connect job level, so
3307 // the transaction does not yet have a connection.
3308 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3309
[email protected]49639fa2011-12-20 23:22:413310 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593311
[email protected]49639fa2011-12-20 23:22:413312 rv = trans->RestartWithAuth(
3313 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013314 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593315
3316 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013317 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593318
3319 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523320 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593321
3322 EXPECT_TRUE(response->headers->IsKeepAlive());
3323 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503324 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593325 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3326
3327 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523328 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503329
[email protected]029c83b62013-01-24 05:28:203330 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3331 TestLoadTimingNotReusedWithPac(load_timing_info,
3332 CONNECT_TIMING_HAS_SSL_TIMES);
3333
[email protected]0b0bf032010-09-21 18:08:503334 trans.reset();
[email protected]102e27c2011-02-23 01:01:313335 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593336}
3337
[email protected]11203f012009-11-12 23:02:313338// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013339// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013340TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233341 // On the second pass, the body read of the auth challenge is synchronous, so
3342 // IsConnectedAndIdle returns false. The socket should still be drained and
3343 // reused. See http://crbug.com/544255.
3344 for (int i = 0; i < 2; ++i) {
3345 HttpRequestInfo request;
3346 request.method = "GET";
3347 request.url = GURL("https://www.example.org/");
3348 // Ensure that proxy authentication is attempted even
3349 // when the no authentication data flag is set.
3350 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103351 request.traffic_annotation =
3352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013353
mmenked39192ee2015-12-09 00:57:233354 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593355 session_deps_.proxy_resolution_service =
3356 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233357 BoundTestNetLog log;
3358 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013360
bnc691fda62016-08-12 00:43:163361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013362
mmenked39192ee2015-12-09 00:57:233363 // Since we have proxy, should try to establish tunnel.
3364 MockWrite data_writes1[] = {
3365 MockWrite(ASYNC, 0,
3366 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3367 "Host: www.example.org:443\r\n"
3368 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013369
bnc691fda62016-08-12 00:43:163370 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233371 // be issuing -- the final header line contains the credentials.
3372 MockWrite(ASYNC, 3,
3373 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3374 "Host: www.example.org:443\r\n"
3375 "Proxy-Connection: keep-alive\r\n"
3376 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3377 };
ttuttle34f63b52015-03-05 04:33:013378
mmenked39192ee2015-12-09 00:57:233379 // The proxy responds to the connect with a 407, using a persistent
3380 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3381 MockRead data_reads1[] = {
3382 // No credentials.
3383 MockRead(ASYNC, 1,
3384 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3385 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3386 "Proxy-Connection: keep-alive\r\n"
3387 "Content-Length: 10\r\n\r\n"),
3388 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013389
mmenked39192ee2015-12-09 00:57:233390 // Wrong credentials (wrong password).
3391 MockRead(ASYNC, 4,
3392 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3393 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3394 "Proxy-Connection: keep-alive\r\n"
3395 "Content-Length: 10\r\n\r\n"),
3396 // No response body because the test stops reading here.
3397 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3398 };
ttuttle34f63b52015-03-05 04:33:013399
mmenked39192ee2015-12-09 00:57:233400 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3401 arraysize(data_writes1));
3402 data1.set_busy_before_sync_reads(true);
3403 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013404
mmenked39192ee2015-12-09 00:57:233405 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013406
bnc691fda62016-08-12 00:43:163407 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013408 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013409
mmenked39192ee2015-12-09 00:57:233410 TestNetLogEntry::List entries;
3411 log.GetEntries(&entries);
3412 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003413 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3414 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233415 ExpectLogContainsSomewhere(
3416 entries, pos,
mikecirone8b85c432016-09-08 19:11:003417 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3418 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013419
bnc691fda62016-08-12 00:43:163420 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233421 ASSERT_TRUE(response);
3422 ASSERT_TRUE(response->headers);
3423 EXPECT_TRUE(response->headers->IsKeepAlive());
3424 EXPECT_EQ(407, response->headers->response_code());
3425 EXPECT_EQ(10, response->headers->GetContentLength());
3426 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3427 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013428
mmenked39192ee2015-12-09 00:57:233429 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013430
mmenked39192ee2015-12-09 00:57:233431 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163432 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3433 callback2.callback());
robpercival214763f2016-07-01 23:27:013434 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013435
bnc691fda62016-08-12 00:43:163436 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233437 ASSERT_TRUE(response);
3438 ASSERT_TRUE(response->headers);
3439 EXPECT_TRUE(response->headers->IsKeepAlive());
3440 EXPECT_EQ(407, response->headers->response_code());
3441 EXPECT_EQ(10, response->headers->GetContentLength());
3442 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3443 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013444
mmenked39192ee2015-12-09 00:57:233445 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3446 // out of scope.
3447 session->CloseAllConnections();
3448 }
ttuttle34f63b52015-03-05 04:33:013449}
3450
3451// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3452// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013453TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233454 // On the second pass, the body read of the auth challenge is synchronous, so
3455 // IsConnectedAndIdle returns false. The socket should still be drained and
3456 // reused. See http://crbug.com/544255.
3457 for (int i = 0; i < 2; ++i) {
3458 HttpRequestInfo request;
3459 request.method = "GET";
3460 request.url = GURL("https://www.example.org/");
3461 // Ensure that proxy authentication is attempted even
3462 // when the no authentication data flag is set.
3463 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103464 request.traffic_annotation =
3465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233466
3467 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593468 session_deps_.proxy_resolution_service =
3469 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233470 BoundTestNetLog log;
3471 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233473
bnc691fda62016-08-12 00:43:163474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233475
3476 // Since we have proxy, should try to establish tunnel.
3477 MockWrite data_writes1[] = {
3478 MockWrite(ASYNC, 0,
3479 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3480 "Host: www.example.org:443\r\n"
3481 "Proxy-Connection: keep-alive\r\n\r\n"),
3482
bnc691fda62016-08-12 00:43:163483 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233484 // be issuing -- the final header line contains the credentials.
3485 MockWrite(ASYNC, 3,
3486 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3487 "Host: www.example.org:443\r\n"
3488 "Proxy-Connection: keep-alive\r\n"
3489 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3490 };
3491
3492 // The proxy responds to the connect with a 407, using a persistent
3493 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3494 MockRead data_reads1[] = {
3495 // No credentials.
3496 MockRead(ASYNC, 1,
3497 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3498 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3499 "Content-Length: 10\r\n\r\n"),
3500 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3501
3502 // Wrong credentials (wrong password).
3503 MockRead(ASYNC, 4,
3504 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3505 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3506 "Content-Length: 10\r\n\r\n"),
3507 // No response body because the test stops reading here.
3508 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3509 };
3510
3511 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3512 arraysize(data_writes1));
3513 data1.set_busy_before_sync_reads(true);
3514 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3515
3516 TestCompletionCallback callback1;
3517
bnc691fda62016-08-12 00:43:163518 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013519 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233520
3521 TestNetLogEntry::List entries;
3522 log.GetEntries(&entries);
3523 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003524 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3525 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233526 ExpectLogContainsSomewhere(
3527 entries, pos,
mikecirone8b85c432016-09-08 19:11:003528 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3529 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233530
bnc691fda62016-08-12 00:43:163531 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233532 ASSERT_TRUE(response);
3533 ASSERT_TRUE(response->headers);
3534 EXPECT_TRUE(response->headers->IsKeepAlive());
3535 EXPECT_EQ(407, response->headers->response_code());
3536 EXPECT_EQ(10, response->headers->GetContentLength());
3537 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3538 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3539
3540 TestCompletionCallback callback2;
3541
3542 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163543 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3544 callback2.callback());
robpercival214763f2016-07-01 23:27:013545 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233546
bnc691fda62016-08-12 00:43:163547 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233548 ASSERT_TRUE(response);
3549 ASSERT_TRUE(response->headers);
3550 EXPECT_TRUE(response->headers->IsKeepAlive());
3551 EXPECT_EQ(407, response->headers->response_code());
3552 EXPECT_EQ(10, response->headers->GetContentLength());
3553 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3554 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3555
3556 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3557 // out of scope.
3558 session->CloseAllConnections();
3559 }
3560}
3561
3562// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3563// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3564// the case the server sends extra data on the original socket, so it can't be
3565// reused.
bncd16676a2016-07-20 16:23:013566TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273567 HttpRequestInfo request;
3568 request.method = "GET";
bncce36dca22015-04-21 22:11:233569 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273570 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293571 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103572 request.traffic_annotation =
3573 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273574
[email protected]2d2697f92009-02-18 21:00:323575 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593576 session_deps_.proxy_resolution_service =
3577 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513578 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073579 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323581
[email protected]2d2697f92009-02-18 21:00:323582 // Since we have proxy, should try to establish tunnel.
3583 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233584 MockWrite(ASYNC, 0,
3585 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173586 "Host: www.example.org:443\r\n"
3587 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233588 };
[email protected]2d2697f92009-02-18 21:00:323589
mmenked39192ee2015-12-09 00:57:233590 // The proxy responds to the connect with a 407, using a persistent, but sends
3591 // extra data, so the socket cannot be reused.
3592 MockRead data_reads1[] = {
3593 // No credentials.
3594 MockRead(ASYNC, 1,
3595 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3596 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3597 "Content-Length: 10\r\n\r\n"),
3598 MockRead(SYNCHRONOUS, 2, "0123456789"),
3599 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3600 };
3601
3602 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233603 // After calling trans->RestartWithAuth(), this is the request we should
3604 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233605 MockWrite(ASYNC, 0,
3606 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173607 "Host: www.example.org:443\r\n"
3608 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233609 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3610
3611 MockWrite(ASYNC, 2,
3612 "GET / HTTP/1.1\r\n"
3613 "Host: www.example.org\r\n"
3614 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323615 };
3616
mmenked39192ee2015-12-09 00:57:233617 MockRead data_reads2[] = {
3618 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323619
mmenked39192ee2015-12-09 00:57:233620 MockRead(ASYNC, 3,
3621 "HTTP/1.1 200 OK\r\n"
3622 "Content-Type: text/html; charset=iso-8859-1\r\n"
3623 "Content-Length: 5\r\n\r\n"),
3624 // No response body because the test stops reading here.
3625 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323626 };
3627
mmenked39192ee2015-12-09 00:57:233628 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3629 arraysize(data_writes1));
3630 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073631 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233632 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3633 arraysize(data_writes2));
3634 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3635 SSLSocketDataProvider ssl(ASYNC, OK);
3636 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323637
[email protected]49639fa2011-12-20 23:22:413638 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323639
bnc87dcefc2017-05-25 12:47:583640 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193641 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323642
mmenked39192ee2015-12-09 00:57:233643 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013644 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233645
mmenke43758e62015-05-04 21:09:463646 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403647 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393648 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003649 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3650 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393651 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403652 entries, pos,
mikecirone8b85c432016-09-08 19:11:003653 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3654 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323655
[email protected]1c773ea12009-04-28 19:58:423656 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243657 ASSERT_TRUE(response);
3658 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323659 EXPECT_TRUE(response->headers->IsKeepAlive());
3660 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423661 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043662 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323663
mmenked39192ee2015-12-09 00:57:233664 LoadTimingInfo load_timing_info;
3665 // CONNECT requests and responses are handled at the connect job level, so
3666 // the transaction does not yet have a connection.
3667 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3668
[email protected]49639fa2011-12-20 23:22:413669 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323670
mmenked39192ee2015-12-09 00:57:233671 rv =
3672 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013673 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323674
[email protected]2d2697f92009-02-18 21:00:323675 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233676 EXPECT_EQ(200, response->headers->response_code());
3677 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423678 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133679
mmenked39192ee2015-12-09 00:57:233680 // The password prompt info should not be set.
3681 EXPECT_FALSE(response->auth_challenge);
3682
3683 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3684 TestLoadTimingNotReusedWithPac(load_timing_info,
3685 CONNECT_TIMING_HAS_SSL_TIMES);
3686
3687 trans.reset();
[email protected]102e27c2011-02-23 01:01:313688 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323689}
3690
mmenkee71e15332015-10-07 16:39:543691// Test the case a proxy closes a socket while the challenge body is being
3692// drained.
bncd16676a2016-07-20 16:23:013693TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543694 HttpRequestInfo request;
3695 request.method = "GET";
3696 request.url = GURL("https://www.example.org/");
3697 // Ensure that proxy authentication is attempted even
3698 // when the no authentication data flag is set.
3699 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103700 request.traffic_annotation =
3701 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543702
3703 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593704 session_deps_.proxy_resolution_service =
3705 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093706 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543707
bnc691fda62016-08-12 00:43:163708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543709
3710 // Since we have proxy, should try to establish tunnel.
3711 MockWrite data_writes1[] = {
3712 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173713 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543714 "Proxy-Connection: keep-alive\r\n\r\n"),
3715 };
3716
3717 // The proxy responds to the connect with a 407, using a persistent
3718 // connection.
3719 MockRead data_reads1[] = {
3720 // No credentials.
3721 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3722 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3723 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3724 // Server hands up in the middle of the body.
3725 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3726 };
3727
3728 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163729 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543730 // be issuing -- the final header line contains the credentials.
3731 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173732 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543733 "Proxy-Connection: keep-alive\r\n"
3734 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3735
3736 MockWrite("GET / HTTP/1.1\r\n"
3737 "Host: www.example.org\r\n"
3738 "Connection: keep-alive\r\n\r\n"),
3739 };
3740
3741 MockRead data_reads2[] = {
3742 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3743
3744 MockRead("HTTP/1.1 200 OK\r\n"),
3745 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3746 MockRead("Content-Length: 5\r\n\r\n"),
3747 MockRead(SYNCHRONOUS, "hello"),
3748 };
3749
3750 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3751 data_writes1, arraysize(data_writes1));
3752 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3753 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3754 data_writes2, arraysize(data_writes2));
3755 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3756 SSLSocketDataProvider ssl(ASYNC, OK);
3757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3758
3759 TestCompletionCallback callback;
3760
tfarina42834112016-09-22 13:38:203761 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013762 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543763
bnc691fda62016-08-12 00:43:163764 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543765 ASSERT_TRUE(response);
3766 ASSERT_TRUE(response->headers);
3767 EXPECT_TRUE(response->headers->IsKeepAlive());
3768 EXPECT_EQ(407, response->headers->response_code());
3769 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3770
bnc691fda62016-08-12 00:43:163771 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013772 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543773
bnc691fda62016-08-12 00:43:163774 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543775 ASSERT_TRUE(response);
3776 ASSERT_TRUE(response->headers);
3777 EXPECT_TRUE(response->headers->IsKeepAlive());
3778 EXPECT_EQ(200, response->headers->response_code());
3779 std::string body;
bnc691fda62016-08-12 00:43:163780 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543781 EXPECT_EQ("hello", body);
3782}
3783
[email protected]a8e9b162009-03-12 00:06:443784// Test that we don't read the response body when we fail to establish a tunnel,
3785// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013786TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273787 HttpRequestInfo request;
3788 request.method = "GET";
bncce36dca22015-04-21 22:11:233789 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103790 request.traffic_annotation =
3791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273792
[email protected]a8e9b162009-03-12 00:06:443793 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593794 session_deps_.proxy_resolution_service =
3795 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443796
danakj1fd259a02016-04-16 03:17:093797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443798
bnc691fda62016-08-12 00:43:163799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443800
[email protected]a8e9b162009-03-12 00:06:443801 // Since we have proxy, should try to establish tunnel.
3802 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173803 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3804 "Host: www.example.org:443\r\n"
3805 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443806 };
3807
3808 // The proxy responds to the connect with a 407.
3809 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243810 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3811 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3812 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233813 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243814 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443815 };
3816
[email protected]31a2bfe2010-02-09 08:03:393817 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3818 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073819 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443820
[email protected]49639fa2011-12-20 23:22:413821 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443822
tfarina42834112016-09-22 13:38:203823 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443825
3826 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013827 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443828
bnc691fda62016-08-12 00:43:163829 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243830 ASSERT_TRUE(response);
3831 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443832 EXPECT_TRUE(response->headers->IsKeepAlive());
3833 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423834 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443835
3836 std::string response_data;
bnc691fda62016-08-12 00:43:163837 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013838 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183839
3840 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313841 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443842}
3843
ttuttle7933c112015-01-06 00:55:243844// Test that we don't pass extraneous headers from the proxy's response to the
3845// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013846TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243847 HttpRequestInfo request;
3848 request.method = "GET";
bncce36dca22015-04-21 22:11:233849 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103850 request.traffic_annotation =
3851 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243852
3853 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593854 session_deps_.proxy_resolution_service =
3855 ProxyResolutionService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243856
danakj1fd259a02016-04-16 03:17:093857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243858
bnc691fda62016-08-12 00:43:163859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243860
3861 // Since we have proxy, should try to establish tunnel.
3862 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173863 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3864 "Host: www.example.org:443\r\n"
3865 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243866 };
3867
3868 // The proxy responds to the connect with a 407.
3869 MockRead data_reads[] = {
3870 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3871 MockRead("X-Foo: bar\r\n"),
3872 MockRead("Set-Cookie: foo=bar\r\n"),
3873 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3874 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233875 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243876 };
3877
3878 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3879 arraysize(data_writes));
3880 session_deps_.socket_factory->AddSocketDataProvider(&data);
3881
3882 TestCompletionCallback callback;
3883
tfarina42834112016-09-22 13:38:203884 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243886
3887 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013888 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243889
bnc691fda62016-08-12 00:43:163890 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243891 ASSERT_TRUE(response);
3892 ASSERT_TRUE(response->headers);
3893 EXPECT_TRUE(response->headers->IsKeepAlive());
3894 EXPECT_EQ(407, response->headers->response_code());
3895 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3896 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3897 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3898
3899 std::string response_data;
bnc691fda62016-08-12 00:43:163900 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013901 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243902
3903 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3904 session->CloseAllConnections();
3905}
3906
[email protected]8fdbcd22010-05-05 02:54:523907// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3908// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013909TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523910 HttpRequestInfo request;
3911 request.method = "GET";
bncce36dca22015-04-21 22:11:233912 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103913 request.traffic_annotation =
3914 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523915
[email protected]cb9bf6ca2011-01-28 13:15:273916 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163918 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273919
[email protected]8fdbcd22010-05-05 02:54:523920 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233921 MockWrite(
3922 "GET / HTTP/1.1\r\n"
3923 "Host: www.example.org\r\n"
3924 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523925 };
3926
3927 MockRead data_reads1[] = {
3928 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3929 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3930 // Large content-length -- won't matter, as connection will be reset.
3931 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063932 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523933 };
3934
3935 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3936 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073937 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523938
[email protected]49639fa2011-12-20 23:22:413939 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523940
tfarina42834112016-09-22 13:38:203941 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523943
3944 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013945 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523946}
3947
[email protected]7a67a8152010-11-05 18:31:103948// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3949// through a non-authenticating proxy. The request should fail with
3950// ERR_UNEXPECTED_PROXY_AUTH.
3951// Note that it is impossible to detect if an HTTP server returns a 407 through
3952// a non-authenticating proxy - there is nothing to indicate whether the
3953// response came from the proxy or the server, so it is treated as if the proxy
3954// issued the challenge.
bncd16676a2016-07-20 16:23:013955TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273956 HttpRequestInfo request;
3957 request.method = "GET";
bncce36dca22015-04-21 22:11:233958 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103959 request.traffic_annotation =
3960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273961
Lily Houghton8c2f97d2018-01-22 05:06:593962 session_deps_.proxy_resolution_service =
3963 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513964 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073965 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103967
[email protected]7a67a8152010-11-05 18:31:103968 // Since we have proxy, should try to establish tunnel.
3969 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173970 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3971 "Host: www.example.org:443\r\n"
3972 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103973
rsleevidb16bb02015-11-12 23:47:173974 MockWrite("GET / HTTP/1.1\r\n"
3975 "Host: www.example.org\r\n"
3976 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103977 };
3978
3979 MockRead data_reads1[] = {
3980 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3981
3982 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3983 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3984 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063985 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103986 };
3987
3988 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3989 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073990 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063991 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073992 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103993
[email protected]49639fa2011-12-20 23:22:413994 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103995
bnc691fda62016-08-12 00:43:163996 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103997
bnc691fda62016-08-12 00:43:163998 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104000
4001 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014002 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464003 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404004 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104005 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004006 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4007 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104008 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404009 entries, pos,
mikecirone8b85c432016-09-08 19:11:004010 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4011 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104012}
[email protected]2df19bb2010-08-25 20:13:464013
mmenke2a1781d2015-10-07 19:25:334014// Test a proxy auth scheme that allows default credentials and a proxy server
4015// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014016TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334017 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4018 HttpRequestInfo request;
4019 request.method = "GET";
4020 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104021 request.traffic_annotation =
4022 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334023
4024 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594025 session_deps_.proxy_resolution_service =
4026 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334027
Jeremy Roman0579ed62017-08-29 15:56:194028 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334029 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194030 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334031 mock_handler->set_allows_default_credentials(true);
4032 auth_handler_factory->AddMockHandler(mock_handler.release(),
4033 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484034 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334035
4036 // Add NetLog just so can verify load timing information gets a NetLog ID.
4037 NetLog net_log;
4038 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094039 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334040
4041 // Since we have proxy, should try to establish tunnel.
4042 MockWrite data_writes1[] = {
4043 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174044 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334045 "Proxy-Connection: keep-alive\r\n\r\n"),
4046 };
4047
4048 // The proxy responds to the connect with a 407, using a non-persistent
4049 // connection.
4050 MockRead data_reads1[] = {
4051 // No credentials.
4052 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4053 MockRead("Proxy-Authenticate: Mock\r\n"),
4054 MockRead("Proxy-Connection: close\r\n\r\n"),
4055 };
4056
4057 // Since the first connection couldn't be reused, need to establish another
4058 // once given credentials.
4059 MockWrite data_writes2[] = {
4060 // After calling trans->RestartWithAuth(), this is the request we should
4061 // be issuing -- the final header line contains the credentials.
4062 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174063 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334064 "Proxy-Connection: keep-alive\r\n"
4065 "Proxy-Authorization: auth_token\r\n\r\n"),
4066
4067 MockWrite("GET / HTTP/1.1\r\n"
4068 "Host: www.example.org\r\n"
4069 "Connection: keep-alive\r\n\r\n"),
4070 };
4071
4072 MockRead data_reads2[] = {
4073 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4074
4075 MockRead("HTTP/1.1 200 OK\r\n"),
4076 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4077 MockRead("Content-Length: 5\r\n\r\n"),
4078 MockRead(SYNCHRONOUS, "hello"),
4079 };
4080
4081 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4082 data_writes1, arraysize(data_writes1));
4083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4084 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4085 data_writes2, arraysize(data_writes2));
4086 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4087 SSLSocketDataProvider ssl(ASYNC, OK);
4088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4089
bnc87dcefc2017-05-25 12:47:584090 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194091 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334092
4093 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204094 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014095 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334096
4097 const HttpResponseInfo* response = trans->GetResponseInfo();
4098 ASSERT_TRUE(response);
4099 ASSERT_TRUE(response->headers);
4100 EXPECT_FALSE(response->headers->IsKeepAlive());
4101 EXPECT_EQ(407, response->headers->response_code());
4102 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4103 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524104 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334105
4106 LoadTimingInfo load_timing_info;
4107 // CONNECT requests and responses are handled at the connect job level, so
4108 // the transaction does not yet have a connection.
4109 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4110
4111 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014112 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334113 response = trans->GetResponseInfo();
4114 ASSERT_TRUE(response);
4115 ASSERT_TRUE(response->headers);
4116 EXPECT_TRUE(response->headers->IsKeepAlive());
4117 EXPECT_EQ(200, response->headers->response_code());
4118 EXPECT_EQ(5, response->headers->GetContentLength());
4119 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4120
4121 // The password prompt info should not be set.
4122 EXPECT_FALSE(response->auth_challenge);
4123
4124 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4125 TestLoadTimingNotReusedWithPac(load_timing_info,
4126 CONNECT_TIMING_HAS_SSL_TIMES);
4127
4128 trans.reset();
4129 session->CloseAllConnections();
4130}
4131
4132// Test a proxy auth scheme that allows default credentials and a proxy server
4133// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014134TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334135 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4136 HttpRequestInfo request;
4137 request.method = "GET";
4138 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104139 request.traffic_annotation =
4140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334141
4142 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594143 session_deps_.proxy_resolution_service =
4144 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334145
Jeremy Roman0579ed62017-08-29 15:56:194146 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334147 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194148 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334149 mock_handler->set_allows_default_credentials(true);
4150 auth_handler_factory->AddMockHandler(mock_handler.release(),
4151 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484152 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334153
4154 // Add NetLog just so can verify load timing information gets a NetLog ID.
4155 NetLog net_log;
4156 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094157 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334158
4159 // Should try to establish tunnel.
4160 MockWrite data_writes1[] = {
4161 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174162 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334163 "Proxy-Connection: keep-alive\r\n\r\n"),
4164
4165 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174166 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334167 "Proxy-Connection: keep-alive\r\n"
4168 "Proxy-Authorization: auth_token\r\n\r\n"),
4169 };
4170
4171 // The proxy responds to the connect with a 407, using a non-persistent
4172 // connection.
4173 MockRead data_reads1[] = {
4174 // No credentials.
4175 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4176 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4177 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4178 };
4179
4180 // Since the first connection was closed, need to establish another once given
4181 // credentials.
4182 MockWrite data_writes2[] = {
4183 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174184 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334185 "Proxy-Connection: keep-alive\r\n"
4186 "Proxy-Authorization: auth_token\r\n\r\n"),
4187
4188 MockWrite("GET / HTTP/1.1\r\n"
4189 "Host: www.example.org\r\n"
4190 "Connection: keep-alive\r\n\r\n"),
4191 };
4192
4193 MockRead data_reads2[] = {
4194 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4195
4196 MockRead("HTTP/1.1 200 OK\r\n"),
4197 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4198 MockRead("Content-Length: 5\r\n\r\n"),
4199 MockRead(SYNCHRONOUS, "hello"),
4200 };
4201
4202 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4203 data_writes1, arraysize(data_writes1));
4204 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4205 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4206 data_writes2, arraysize(data_writes2));
4207 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4208 SSLSocketDataProvider ssl(ASYNC, OK);
4209 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4210
bnc87dcefc2017-05-25 12:47:584211 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194212 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334213
4214 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204215 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014216 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334217
4218 const HttpResponseInfo* response = trans->GetResponseInfo();
4219 ASSERT_TRUE(response);
4220 ASSERT_TRUE(response->headers);
4221 EXPECT_TRUE(response->headers->IsKeepAlive());
4222 EXPECT_EQ(407, response->headers->response_code());
4223 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4224 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4225 EXPECT_FALSE(response->auth_challenge);
4226
4227 LoadTimingInfo load_timing_info;
4228 // CONNECT requests and responses are handled at the connect job level, so
4229 // the transaction does not yet have a connection.
4230 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4231
4232 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014233 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334234
4235 response = trans->GetResponseInfo();
4236 ASSERT_TRUE(response);
4237 ASSERT_TRUE(response->headers);
4238 EXPECT_TRUE(response->headers->IsKeepAlive());
4239 EXPECT_EQ(200, response->headers->response_code());
4240 EXPECT_EQ(5, response->headers->GetContentLength());
4241 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4242
4243 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524244 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334245
4246 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4247 TestLoadTimingNotReusedWithPac(load_timing_info,
4248 CONNECT_TIMING_HAS_SSL_TIMES);
4249
4250 trans.reset();
4251 session->CloseAllConnections();
4252}
4253
4254// Test a proxy auth scheme that allows default credentials and a proxy server
4255// that hangs up when credentials are initially sent, and hangs up again when
4256// they are retried.
bncd16676a2016-07-20 16:23:014257TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334258 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4259 HttpRequestInfo request;
4260 request.method = "GET";
4261 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104262 request.traffic_annotation =
4263 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334264
4265 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594266 session_deps_.proxy_resolution_service =
4267 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334268
Jeremy Roman0579ed62017-08-29 15:56:194269 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334270 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194271 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334272 mock_handler->set_allows_default_credentials(true);
4273 auth_handler_factory->AddMockHandler(mock_handler.release(),
4274 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484275 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334276
4277 // Add NetLog just so can verify load timing information gets a NetLog ID.
4278 NetLog net_log;
4279 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094280 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334281
4282 // Should try to establish tunnel.
4283 MockWrite data_writes1[] = {
4284 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174285 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334286 "Proxy-Connection: keep-alive\r\n\r\n"),
4287
4288 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174289 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334290 "Proxy-Connection: keep-alive\r\n"
4291 "Proxy-Authorization: auth_token\r\n\r\n"),
4292 };
4293
4294 // The proxy responds to the connect with a 407, and then hangs up after the
4295 // second request is sent.
4296 MockRead data_reads1[] = {
4297 // No credentials.
4298 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4299 MockRead("Content-Length: 0\r\n"),
4300 MockRead("Proxy-Connection: keep-alive\r\n"),
4301 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4302 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4303 };
4304
4305 // HttpNetworkTransaction sees a reused connection that was closed with
4306 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4307 // request.
4308 MockWrite data_writes2[] = {
4309 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174310 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334311 "Proxy-Connection: keep-alive\r\n\r\n"),
4312 };
4313
4314 // The proxy, having had more than enough of us, just hangs up.
4315 MockRead data_reads2[] = {
4316 // No credentials.
4317 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4318 };
4319
4320 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4321 data_writes1, arraysize(data_writes1));
4322 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4323 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4324 data_writes2, arraysize(data_writes2));
4325 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4326
bnc87dcefc2017-05-25 12:47:584327 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194328 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334329
4330 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204331 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014332 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334333
4334 const HttpResponseInfo* response = trans->GetResponseInfo();
4335 ASSERT_TRUE(response);
4336 ASSERT_TRUE(response->headers);
4337 EXPECT_TRUE(response->headers->IsKeepAlive());
4338 EXPECT_EQ(407, response->headers->response_code());
4339 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4340 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4341 EXPECT_FALSE(response->auth_challenge);
4342
4343 LoadTimingInfo load_timing_info;
4344 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4345
4346 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014347 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334348
4349 trans.reset();
4350 session->CloseAllConnections();
4351}
4352
4353// Test a proxy auth scheme that allows default credentials and a proxy server
4354// that hangs up when credentials are initially sent, and sends a challenge
4355// again they are retried.
bncd16676a2016-07-20 16:23:014356TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334357 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4358 HttpRequestInfo request;
4359 request.method = "GET";
4360 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104361 request.traffic_annotation =
4362 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334363
4364 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594365 session_deps_.proxy_resolution_service =
4366 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334367
Jeremy Roman0579ed62017-08-29 15:56:194368 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334369 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194370 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334371 mock_handler->set_allows_default_credentials(true);
4372 auth_handler_factory->AddMockHandler(mock_handler.release(),
4373 HttpAuth::AUTH_PROXY);
4374 // Add another handler for the second challenge. It supports default
4375 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194376 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334377 mock_handler->set_allows_default_credentials(true);
4378 auth_handler_factory->AddMockHandler(mock_handler.release(),
4379 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484380 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334381
4382 // Add NetLog just so can verify load timing information gets a NetLog ID.
4383 NetLog net_log;
4384 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094385 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334386
4387 // Should try to establish tunnel.
4388 MockWrite data_writes1[] = {
4389 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174390 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334391 "Proxy-Connection: keep-alive\r\n\r\n"),
4392 };
4393
4394 // The proxy responds to the connect with a 407, using a non-persistent
4395 // connection.
4396 MockRead data_reads1[] = {
4397 // No credentials.
4398 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4399 MockRead("Proxy-Authenticate: Mock\r\n"),
4400 MockRead("Proxy-Connection: close\r\n\r\n"),
4401 };
4402
4403 // Since the first connection was closed, need to establish another once given
4404 // credentials.
4405 MockWrite data_writes2[] = {
4406 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174407 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334408 "Proxy-Connection: keep-alive\r\n"
4409 "Proxy-Authorization: auth_token\r\n\r\n"),
4410 };
4411
4412 MockRead data_reads2[] = {
4413 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4414 MockRead("Proxy-Authenticate: Mock\r\n"),
4415 MockRead("Proxy-Connection: close\r\n\r\n"),
4416 };
4417
4418 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4419 data_writes1, arraysize(data_writes1));
4420 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4421 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4422 data_writes2, arraysize(data_writes2));
4423 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4424 SSLSocketDataProvider ssl(ASYNC, OK);
4425 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4426
bnc87dcefc2017-05-25 12:47:584427 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194428 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334429
4430 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204431 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014432 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334433
4434 const HttpResponseInfo* response = trans->GetResponseInfo();
4435 ASSERT_TRUE(response);
4436 ASSERT_TRUE(response->headers);
4437 EXPECT_EQ(407, response->headers->response_code());
4438 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4439 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4440 EXPECT_FALSE(response->auth_challenge);
4441
4442 LoadTimingInfo load_timing_info;
4443 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4444
4445 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014446 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334447 response = trans->GetResponseInfo();
4448 ASSERT_TRUE(response);
4449 ASSERT_TRUE(response->headers);
4450 EXPECT_EQ(407, response->headers->response_code());
4451 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4452 EXPECT_TRUE(response->auth_challenge);
4453
4454 trans.reset();
4455 session->CloseAllConnections();
4456}
4457
asankae2257db2016-10-11 22:03:164458// A more nuanced test than GenerateAuthToken test which asserts that
4459// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4460// unnecessarily invalidated, and that if the server co-operates, the
4461// authentication handshake can continue with the same scheme but with a
4462// different identity.
4463TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4464 HttpRequestInfo request;
4465 request.method = "GET";
4466 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104467 request.traffic_annotation =
4468 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164469
Jeremy Roman0579ed62017-08-29 15:56:194470 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164471 auth_handler_factory->set_do_init_from_challenge(true);
4472
4473 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194474 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164475 mock_handler->set_allows_default_credentials(true);
4476 mock_handler->set_allows_explicit_credentials(true);
4477 mock_handler->set_connection_based(true);
4478 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4479 auth_handler_factory->AddMockHandler(mock_handler.release(),
4480 HttpAuth::AUTH_SERVER);
4481
4482 // Add another handler for the second challenge. It supports default
4483 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194484 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164485 mock_handler->set_allows_default_credentials(true);
4486 mock_handler->set_allows_explicit_credentials(true);
4487 mock_handler->set_connection_based(true);
4488 auth_handler_factory->AddMockHandler(mock_handler.release(),
4489 HttpAuth::AUTH_SERVER);
4490 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4491
4492 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4493
4494 MockWrite data_writes1[] = {
4495 MockWrite("GET / HTTP/1.1\r\n"
4496 "Host: www.example.org\r\n"
4497 "Connection: keep-alive\r\n\r\n"),
4498 };
4499
4500 MockRead data_reads1[] = {
4501 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4502 "WWW-Authenticate: Mock\r\n"
4503 "Connection: keep-alive\r\n\r\n"),
4504 };
4505
4506 // Identical to data_writes1[]. The AuthHandler encounters a
4507 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4508 // transaction procceds without an authorization header.
4509 MockWrite data_writes2[] = {
4510 MockWrite("GET / HTTP/1.1\r\n"
4511 "Host: www.example.org\r\n"
4512 "Connection: keep-alive\r\n\r\n"),
4513 };
4514
4515 MockRead data_reads2[] = {
4516 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4517 "WWW-Authenticate: Mock\r\n"
4518 "Connection: keep-alive\r\n\r\n"),
4519 };
4520
4521 MockWrite data_writes3[] = {
4522 MockWrite("GET / HTTP/1.1\r\n"
4523 "Host: www.example.org\r\n"
4524 "Connection: keep-alive\r\n"
4525 "Authorization: auth_token\r\n\r\n"),
4526 };
4527
4528 MockRead data_reads3[] = {
4529 MockRead("HTTP/1.1 200 OK\r\n"
4530 "Content-Length: 5\r\n"
4531 "Content-Type: text/plain\r\n"
4532 "Connection: keep-alive\r\n\r\n"
4533 "Hello"),
4534 };
4535
4536 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4537 data_writes1, arraysize(data_writes1));
4538 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4539
4540 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4541 data_writes2, arraysize(data_writes2));
4542 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4543
4544 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4545 data_writes3, arraysize(data_writes3));
4546 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4547
bnc87dcefc2017-05-25 12:47:584548 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194549 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164550
4551 TestCompletionCallback callback;
4552 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4553 EXPECT_THAT(callback.GetResult(rv), IsOk());
4554
4555 const HttpResponseInfo* response = trans->GetResponseInfo();
4556 ASSERT_TRUE(response);
4557 ASSERT_TRUE(response->headers);
4558 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4559
4560 // The following three tests assert that an authentication challenge was
4561 // received and that the stack is ready to respond to the challenge using
4562 // ambient credentials.
4563 EXPECT_EQ(401, response->headers->response_code());
4564 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4565 EXPECT_FALSE(response->auth_challenge);
4566
4567 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4568 EXPECT_THAT(callback.GetResult(rv), IsOk());
4569 response = trans->GetResponseInfo();
4570 ASSERT_TRUE(response);
4571 ASSERT_TRUE(response->headers);
4572
4573 // The following three tests assert that an authentication challenge was
4574 // received and that the stack needs explicit credentials before it is ready
4575 // to respond to the challenge.
4576 EXPECT_EQ(401, response->headers->response_code());
4577 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4578 EXPECT_TRUE(response->auth_challenge);
4579
4580 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4581 EXPECT_THAT(callback.GetResult(rv), IsOk());
4582 response = trans->GetResponseInfo();
4583 ASSERT_TRUE(response);
4584 ASSERT_TRUE(response->headers);
4585 EXPECT_EQ(200, response->headers->response_code());
4586
4587 trans.reset();
4588 session->CloseAllConnections();
4589}
4590
Matt Menked1eb6d42018-01-17 04:54:064591// Proxy resolver that returns a proxy with the same host and port for different
4592// schemes, based on the path of the URL being requests.
4593class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4594 public:
4595 SameProxyWithDifferentSchemesProxyResolver() {}
4596 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4597
4598 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4599
4600 static HostPortPair ProxyHostPortPair() {
4601 return HostPortPair::FromString(ProxyHostPortPairAsString());
4602 }
4603
4604 // ProxyResolver implementation.
4605 int GetProxyForURL(const GURL& url,
4606 ProxyInfo* results,
4607 const CompletionCallback& callback,
4608 std::unique_ptr<Request>* request,
4609 const NetLogWithSource& /*net_log*/) override {
4610 *results = ProxyInfo();
4611 if (url.path() == "/socks4") {
4612 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4613 return OK;
4614 }
4615 if (url.path() == "/socks5") {
4616 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4617 return OK;
4618 }
4619 if (url.path() == "/http") {
4620 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4621 return OK;
4622 }
4623 if (url.path() == "/https") {
4624 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4625 return OK;
4626 }
4627 NOTREACHED();
4628 return ERR_NOT_IMPLEMENTED;
4629 }
4630
4631 private:
4632 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4633};
4634
4635class SameProxyWithDifferentSchemesProxyResolverFactory
4636 : public ProxyResolverFactory {
4637 public:
4638 SameProxyWithDifferentSchemesProxyResolverFactory()
4639 : ProxyResolverFactory(false) {}
4640
4641 int CreateProxyResolver(
4642 const scoped_refptr<ProxyResolverScriptData>& pac_script,
4643 std::unique_ptr<ProxyResolver>* resolver,
4644 const CompletionCallback& callback,
4645 std::unique_ptr<Request>* request) override {
4646 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4647 return OK;
4648 }
4649
4650 private:
4651 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4652};
4653
4654// Check that when different proxy schemes are all applied to a proxy at the
4655// same address, the sonnections are not grouped together. i.e., a request to
4656// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4657// request to foo.com using proxy.com as an HTTP proxy.
4658TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Lily Houghton8c2f97d2018-01-22 05:06:594659 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Matt Menked1eb6d42018-01-17 04:54:064660 std::make_unique<ProxyConfigServiceFixed>(
4661 ProxyConfig::CreateAutoDetect()),
4662 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4663 nullptr);
4664
4665 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4666
4667 MockWrite socks_writes[] = {
4668 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4669 kSOCKS4OkRequestLocalHostPort80Length),
4670 MockWrite(SYNCHRONOUS,
4671 "GET /socks4 HTTP/1.1\r\n"
4672 "Host: test\r\n"
4673 "Connection: keep-alive\r\n\r\n"),
4674 };
4675 MockRead socks_reads[] = {
4676 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4677 MockRead("HTTP/1.0 200 OK\r\n"
4678 "Connection: keep-alive\r\n"
4679 "Content-Length: 15\r\n\r\n"
4680 "SOCKS4 Response"),
4681 };
4682 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4683 socks_writes, arraysize(socks_writes));
4684 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4685
4686 const char kSOCKS5Request[] = {
4687 0x05, // Version
4688 0x01, // Command (CONNECT)
4689 0x00, // Reserved
4690 0x03, // Address type (DOMAINNAME)
4691 0x04, // Length of domain (4)
4692 't', 'e', 's', 't', // Domain string
4693 0x00, 0x50, // 16-bit port (80)
4694 };
4695 MockWrite socks5_writes[] = {
4696 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4697 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4698 MockWrite(SYNCHRONOUS,
4699 "GET /socks5 HTTP/1.1\r\n"
4700 "Host: test\r\n"
4701 "Connection: keep-alive\r\n\r\n"),
4702 };
4703 MockRead socks5_reads[] = {
4704 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4705 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4706 MockRead("HTTP/1.0 200 OK\r\n"
4707 "Connection: keep-alive\r\n"
4708 "Content-Length: 15\r\n\r\n"
4709 "SOCKS5 Response"),
4710 };
4711 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4712 socks5_writes, arraysize(socks5_writes));
4713 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4714
4715 MockWrite http_writes[] = {
4716 MockWrite(SYNCHRONOUS,
4717 "GET http://test/http HTTP/1.1\r\n"
4718 "Host: test\r\n"
4719 "Proxy-Connection: keep-alive\r\n\r\n"),
4720 };
4721 MockRead http_reads[] = {
4722 MockRead("HTTP/1.1 200 OK\r\n"
4723 "Proxy-Connection: keep-alive\r\n"
4724 "Content-Length: 13\r\n\r\n"
4725 "HTTP Response"),
4726 };
4727 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4728 http_writes, arraysize(http_writes));
4729 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4730
4731 MockWrite https_writes[] = {
4732 MockWrite(SYNCHRONOUS,
4733 "GET http://test/https HTTP/1.1\r\n"
4734 "Host: test\r\n"
4735 "Proxy-Connection: keep-alive\r\n\r\n"),
4736 };
4737 MockRead https_reads[] = {
4738 MockRead("HTTP/1.1 200 OK\r\n"
4739 "Proxy-Connection: keep-alive\r\n"
4740 "Content-Length: 14\r\n\r\n"
4741 "HTTPS Response"),
4742 };
4743 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4744 https_writes, arraysize(https_writes));
4745 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4746 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4747 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4748
4749 struct TestCase {
4750 GURL url;
4751 std::string expected_response;
4752 // How many idle sockets there should be in the SOCKS proxy socket pool
4753 // after the test.
4754 int expected_idle_socks_sockets;
4755 // How many idle sockets there should be in the HTTP proxy socket pool after
4756 // the test.
4757 int expected_idle_http_sockets;
4758 } const kTestCases[] = {
4759 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4760 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4761 {GURL("http://test/http"), "HTTP Response", 2, 1},
4762 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4763 };
4764
4765 for (const auto& test_case : kTestCases) {
4766 HttpRequestInfo request;
4767 request.method = "GET";
4768 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:104769 request.traffic_annotation =
4770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064771 std::unique_ptr<HttpNetworkTransaction> trans =
4772 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4773 session.get());
4774 TestCompletionCallback callback;
4775 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4776 EXPECT_THAT(callback.GetResult(rv), IsOk());
4777
4778 const HttpResponseInfo* response = trans->GetResponseInfo();
4779 ASSERT_TRUE(response);
4780 ASSERT_TRUE(response->headers);
4781 EXPECT_EQ(200, response->headers->response_code());
4782 std::string response_data;
4783 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4784 EXPECT_EQ(test_case.expected_response, response_data);
4785
4786 // Return the socket to the socket pool, so can make sure it's not used for
4787 // the next requests.
4788 trans.reset();
4789 base::RunLoop().RunUntilIdle();
4790
4791 // Check the number of idle sockets in the pool, to make sure that used
4792 // sockets are indeed being returned to the socket pool. If each request
4793 // doesn't return an idle socket to the pool, the test would incorrectly
4794 // pass.
4795 EXPECT_EQ(
4796 test_case.expected_idle_socks_sockets,
4797 session
4798 ->GetSocketPoolForSOCKSProxy(
4799 HttpNetworkSession::NORMAL_SOCKET_POOL,
4800 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4801 ->IdleSocketCount());
4802 EXPECT_EQ(
4803 test_case.expected_idle_http_sockets,
4804 session
4805 ->GetSocketPoolForHTTPProxy(
4806 HttpNetworkSession::NORMAL_SOCKET_POOL,
4807 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4808 ->IdleSocketCount());
4809 }
4810}
4811
[email protected]029c83b62013-01-24 05:28:204812// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014813TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204814 HttpRequestInfo request1;
4815 request1.method = "GET";
bncce36dca22015-04-21 22:11:234816 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104817 request1.traffic_annotation =
4818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204819
4820 HttpRequestInfo request2;
4821 request2.method = "GET";
bncce36dca22015-04-21 22:11:234822 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104823 request2.traffic_annotation =
4824 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204825
4826 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594827 session_deps_.proxy_resolution_service =
4828 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514829 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074830 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204832
4833 // Since we have proxy, should try to establish tunnel.
4834 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174835 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4836 "Host: www.example.org:443\r\n"
4837 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204838
rsleevidb16bb02015-11-12 23:47:174839 MockWrite("GET /1 HTTP/1.1\r\n"
4840 "Host: www.example.org\r\n"
4841 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204842
rsleevidb16bb02015-11-12 23:47:174843 MockWrite("GET /2 HTTP/1.1\r\n"
4844 "Host: www.example.org\r\n"
4845 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204846 };
4847
4848 // The proxy responds to the connect with a 407, using a persistent
4849 // connection.
4850 MockRead data_reads1[] = {
4851 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4852
4853 MockRead("HTTP/1.1 200 OK\r\n"),
4854 MockRead("Content-Length: 1\r\n\r\n"),
4855 MockRead(SYNCHRONOUS, "1"),
4856
4857 MockRead("HTTP/1.1 200 OK\r\n"),
4858 MockRead("Content-Length: 2\r\n\r\n"),
4859 MockRead(SYNCHRONOUS, "22"),
4860 };
4861
4862 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4863 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074864 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204865 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074866 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204867
4868 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584869 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194870 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204871
4872 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204874
4875 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014876 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204877
4878 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524879 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474880 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524881 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204882 EXPECT_EQ(1, response1->headers->GetContentLength());
4883
4884 LoadTimingInfo load_timing_info1;
4885 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4886 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4887
4888 trans1.reset();
4889
4890 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584891 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194892 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204893
4894 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204896
4897 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014898 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204899
4900 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524901 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474902 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524903 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204904 EXPECT_EQ(2, response2->headers->GetContentLength());
4905
4906 LoadTimingInfo load_timing_info2;
4907 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4908 TestLoadTimingReused(load_timing_info2);
4909
4910 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4911
4912 trans2.reset();
4913 session->CloseAllConnections();
4914}
4915
4916// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014917TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204918 HttpRequestInfo request1;
4919 request1.method = "GET";
bncce36dca22015-04-21 22:11:234920 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104921 request1.traffic_annotation =
4922 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204923
4924 HttpRequestInfo request2;
4925 request2.method = "GET";
bncce36dca22015-04-21 22:11:234926 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104927 request2.traffic_annotation =
4928 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204929
4930 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594931 session_deps_.proxy_resolution_service =
4932 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514933 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074934 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094935 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204936
4937 // Since we have proxy, should try to establish tunnel.
4938 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174939 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4940 "Host: www.example.org:443\r\n"
4941 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204942
rsleevidb16bb02015-11-12 23:47:174943 MockWrite("GET /1 HTTP/1.1\r\n"
4944 "Host: www.example.org\r\n"
4945 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204946
rsleevidb16bb02015-11-12 23:47:174947 MockWrite("GET /2 HTTP/1.1\r\n"
4948 "Host: www.example.org\r\n"
4949 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204950 };
4951
4952 // The proxy responds to the connect with a 407, using a persistent
4953 // connection.
4954 MockRead data_reads1[] = {
4955 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4956
4957 MockRead("HTTP/1.1 200 OK\r\n"),
4958 MockRead("Content-Length: 1\r\n\r\n"),
4959 MockRead(SYNCHRONOUS, "1"),
4960
4961 MockRead("HTTP/1.1 200 OK\r\n"),
4962 MockRead("Content-Length: 2\r\n\r\n"),
4963 MockRead(SYNCHRONOUS, "22"),
4964 };
4965
4966 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4967 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074968 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204969 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204971
4972 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584973 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194974 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204975
4976 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204978
4979 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014980 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204981
4982 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524983 ASSERT_TRUE(response1);
4984 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204985 EXPECT_EQ(1, response1->headers->GetContentLength());
4986
4987 LoadTimingInfo load_timing_info1;
4988 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4989 TestLoadTimingNotReusedWithPac(load_timing_info1,
4990 CONNECT_TIMING_HAS_SSL_TIMES);
4991
4992 trans1.reset();
4993
4994 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584995 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194996 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204997
4998 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205000
5001 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015002 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205003
5004 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525005 ASSERT_TRUE(response2);
5006 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205007 EXPECT_EQ(2, response2->headers->GetContentLength());
5008
5009 LoadTimingInfo load_timing_info2;
5010 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5011 TestLoadTimingReusedWithPac(load_timing_info2);
5012
5013 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5014
5015 trans2.reset();
5016 session->CloseAllConnections();
5017}
5018
[email protected]2df19bb2010-08-25 20:13:465019// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015020TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275021 HttpRequestInfo request;
5022 request.method = "GET";
bncce36dca22015-04-21 22:11:235023 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105024 request.traffic_annotation =
5025 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275026
[email protected]2df19bb2010-08-25 20:13:465027 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595028 session_deps_.proxy_resolution_service =
5029 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515030 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075031 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465033
[email protected]2df19bb2010-08-25 20:13:465034 // Since we have proxy, should use full url
5035 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235036 MockWrite(
5037 "GET http://www.example.org/ HTTP/1.1\r\n"
5038 "Host: www.example.org\r\n"
5039 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465040 };
5041
5042 MockRead data_reads1[] = {
5043 MockRead("HTTP/1.1 200 OK\r\n"),
5044 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5045 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065046 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465047 };
5048
5049 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5050 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075051 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065052 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465054
[email protected]49639fa2011-12-20 23:22:415055 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465056
bnc691fda62016-08-12 00:43:165057 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505058
bnc691fda62016-08-12 00:43:165059 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465061
5062 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015063 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465064
[email protected]58e32bb2013-01-21 18:23:255065 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165066 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255067 TestLoadTimingNotReused(load_timing_info,
5068 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5069
bnc691fda62016-08-12 00:43:165070 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525071 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465072
tbansal2ecbbc72016-10-06 17:15:475073 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465074 EXPECT_TRUE(response->headers->IsKeepAlive());
5075 EXPECT_EQ(200, response->headers->response_code());
5076 EXPECT_EQ(100, response->headers->GetContentLength());
5077 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5078
5079 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525080 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465081}
5082
[email protected]7642b5ae2010-09-01 20:55:175083// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015084TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275085 HttpRequestInfo request;
5086 request.method = "GET";
bncce36dca22015-04-21 22:11:235087 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105088 request.traffic_annotation =
5089 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275090
[email protected]7642b5ae2010-09-01 20:55:175091 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595092 session_deps_.proxy_resolution_service =
5093 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515094 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075095 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095096 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175097
bncce36dca22015-04-21 22:11:235098 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415099 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455100 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415101 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175102
bnc42331402016-07-25 13:36:155103 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415104 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175105 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415106 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175107 };
5108
rch8e6c6c42015-05-01 14:05:135109 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5110 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075111 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175112
[email protected]8ddf8322012-02-23 18:08:065113 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365114 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175116
[email protected]49639fa2011-12-20 23:22:415117 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175118
bnc691fda62016-08-12 00:43:165119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505120
bnc691fda62016-08-12 00:43:165121 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175123
5124 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015125 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175126
[email protected]58e32bb2013-01-21 18:23:255127 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165128 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255129 TestLoadTimingNotReused(load_timing_info,
5130 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5131
bnc691fda62016-08-12 00:43:165132 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525133 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475134 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525135 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025136 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175137
5138 std::string response_data;
bnc691fda62016-08-12 00:43:165139 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235140 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175141}
5142
[email protected]1c173852014-06-19 12:51:505143// Verifies that a session which races and wins against the owning transaction
5144// (completing prior to host resolution), doesn't fail the transaction.
5145// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015146TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505147 HttpRequestInfo request;
5148 request.method = "GET";
bncce36dca22015-04-21 22:11:235149 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105150 request.traffic_annotation =
5151 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505152
5153 // Configure SPDY proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595154 session_deps_.proxy_resolution_service =
5155 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515156 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505157 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505159
bncce36dca22015-04-21 22:11:235160 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415161 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455162 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415163 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505164
bnc42331402016-07-25 13:36:155165 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415166 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505167 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415168 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505169 };
5170
rch8e6c6c42015-05-01 14:05:135171 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5172 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505173 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5174
5175 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365176 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5178
5179 TestCompletionCallback callback1;
5180
bnc691fda62016-08-12 00:43:165181 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505182
5183 // Stall the hostname resolution begun by the transaction.
5184 session_deps_.host_resolver->set_synchronous_mode(false);
5185 session_deps_.host_resolver->set_ondemand_mode(true);
5186
bnc691fda62016-08-12 00:43:165187 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015188 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505189
5190 // Race a session to the proxy, which completes first.
5191 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045192 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5193 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505194 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525195 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505196
5197 // Unstall the resolution begun by the transaction.
5198 session_deps_.host_resolver->set_ondemand_mode(true);
5199 session_deps_.host_resolver->ResolveAllPending();
5200
5201 EXPECT_FALSE(callback1.have_result());
5202 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015203 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505204
bnc691fda62016-08-12 00:43:165205 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525206 ASSERT_TRUE(response);
5207 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025208 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505209
5210 std::string response_data;
bnc691fda62016-08-12 00:43:165211 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505212 EXPECT_EQ(kUploadData, response_data);
5213}
5214
[email protected]dc7bd1c52010-11-12 00:01:135215// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015216TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275217 HttpRequestInfo request;
5218 request.method = "GET";
bncce36dca22015-04-21 22:11:235219 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105220 request.traffic_annotation =
5221 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275222
[email protected]79cb5c12011-09-12 13:12:045223 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595224 session_deps_.proxy_resolution_service =
5225 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515226 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075227 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135229
[email protected]dc7bd1c52010-11-12 00:01:135230 // The first request will be a bare GET, the second request will be a
5231 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455232 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415233 SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485234 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385235 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135236 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465237 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135238 };
bncdf80d44fd2016-07-15 20:27:415239 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5240 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485241 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135242 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415243 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135244 };
5245
5246 // The first response is a 407 proxy authentication challenge, and the second
5247 // response will be a 200 response since the second request includes a valid
5248 // Authorization header.
5249 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465250 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135251 };
bnc42331402016-07-25 13:36:155252 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235253 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415254 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5255 SpdySerializedFrame body_authentication(
5256 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155257 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415258 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135259 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415260 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465261 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415262 CreateMockRead(resp_data, 4),
5263 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135264 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135265 };
5266
rch8e6c6c42015-05-01 14:05:135267 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5268 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075269 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135270
[email protected]8ddf8322012-02-23 18:08:065271 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365272 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135274
[email protected]49639fa2011-12-20 23:22:415275 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135276
bnc691fda62016-08-12 00:43:165277 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135278
bnc691fda62016-08-12 00:43:165279 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135281
5282 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015283 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135284
bnc691fda62016-08-12 00:43:165285 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135286
wezca1070932016-05-26 20:30:525287 ASSERT_TRUE(response);
5288 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135289 EXPECT_EQ(407, response->headers->response_code());
5290 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435291 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135292
[email protected]49639fa2011-12-20 23:22:415293 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135294
bnc691fda62016-08-12 00:43:165295 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135297
5298 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015299 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135300
bnc691fda62016-08-12 00:43:165301 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135302
wezca1070932016-05-26 20:30:525303 ASSERT_TRUE(response_restart);
5304 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135305 EXPECT_EQ(200, response_restart->headers->response_code());
5306 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525307 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135308}
5309
[email protected]d9da5fe2010-10-13 22:37:165310// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015311TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275312 HttpRequestInfo request;
5313 request.method = "GET";
bncce36dca22015-04-21 22:11:235314 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105315 request.traffic_annotation =
5316 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275317
[email protected]d9da5fe2010-10-13 22:37:165318 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595319 session_deps_.proxy_resolution_service =
5320 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515321 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075322 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095323 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165324
bnc691fda62016-08-12 00:43:165325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165326
bncce36dca22015-04-21 22:11:235327 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415328 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235329 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5330 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165331
bncce36dca22015-04-21 22:11:235332 const char get[] =
5333 "GET / HTTP/1.1\r\n"
5334 "Host: www.example.org\r\n"
5335 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415336 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195337 spdy_util_.ConstructSpdyDataFrame(1, get, false));
bnc42331402016-07-25 13:36:155338 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165339 const char resp[] = "HTTP/1.1 200 OK\r\n"
5340 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415341 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195342 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
bncdf80d44fd2016-07-15 20:27:415343 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195344 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
bncdf80d44fd2016-07-15 20:27:415345 SpdySerializedFrame window_update(
5346 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045347
5348 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415349 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5350 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045351 };
5352
[email protected]d9da5fe2010-10-13 22:37:165353 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415354 CreateMockRead(conn_resp, 1, ASYNC),
5355 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5356 CreateMockRead(wrapped_body, 4, ASYNC),
5357 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135358 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165359 };
5360
rch8e6c6c42015-05-01 14:05:135361 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5362 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075363 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165364
[email protected]8ddf8322012-02-23 18:08:065365 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365366 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065368 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165370
[email protected]49639fa2011-12-20 23:22:415371 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165372
bnc691fda62016-08-12 00:43:165373 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165375
5376 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015377 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165378
[email protected]58e32bb2013-01-21 18:23:255379 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165380 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255381 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5382
bnc691fda62016-08-12 00:43:165383 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525384 ASSERT_TRUE(response);
5385 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165386 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5387
5388 std::string response_data;
bnc691fda62016-08-12 00:43:165389 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165390 EXPECT_EQ("1234567890", response_data);
5391}
5392
5393// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015394TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5395 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385396
[email protected]cb9bf6ca2011-01-28 13:15:275397 HttpRequestInfo request;
5398 request.method = "GET";
bncce36dca22015-04-21 22:11:235399 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105400 request.traffic_annotation =
5401 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275402
[email protected]d9da5fe2010-10-13 22:37:165403 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595404 session_deps_.proxy_resolution_service =
5405 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515406 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075407 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095408 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165409
bnc691fda62016-08-12 00:43:165410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165411
bncce36dca22015-04-21 22:11:235412 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415413 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235414 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5415 // fetch https://www.example.org/ via SPDY
5416 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415417 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495418 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415419 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155420 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415421 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155422 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415423 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025424 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415425 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5426 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025427 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415428 SpdySerializedFrame window_update_get_resp(
5429 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5430 SpdySerializedFrame window_update_body(
5431 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045432
5433 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415434 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5435 CreateMockWrite(window_update_get_resp, 6),
5436 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045437 };
5438
[email protected]d9da5fe2010-10-13 22:37:165439 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415440 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095441 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415442 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5443 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135444 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165445 };
5446
rch32320842015-05-16 15:57:095447 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5448 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075449 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165450
[email protected]8ddf8322012-02-23 18:08:065451 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365452 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075453 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065454 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365455 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165457
[email protected]49639fa2011-12-20 23:22:415458 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165459
bnc691fda62016-08-12 00:43:165460 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165462
rch32320842015-05-16 15:57:095463 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555464 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095465 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595466 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165467 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015468 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165469
[email protected]58e32bb2013-01-21 18:23:255470 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165471 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255472 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5473
bnc691fda62016-08-12 00:43:165474 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525475 ASSERT_TRUE(response);
5476 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025477 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165478
5479 std::string response_data;
bnc691fda62016-08-12 00:43:165480 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235481 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165482}
5483
5484// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015485TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275486 HttpRequestInfo request;
5487 request.method = "GET";
bncce36dca22015-04-21 22:11:235488 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105489 request.traffic_annotation =
5490 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275491
[email protected]d9da5fe2010-10-13 22:37:165492 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595493 session_deps_.proxy_resolution_service =
5494 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515495 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075496 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095497 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165498
bnc691fda62016-08-12 00:43:165499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165500
bncce36dca22015-04-21 22:11:235501 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415502 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235503 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415504 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085505 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165506
5507 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415508 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165509 };
5510
bnc42331402016-07-25 13:36:155511 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415512 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165513 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415514 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165515 };
5516
rch8e6c6c42015-05-01 14:05:135517 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5518 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075519 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165520
[email protected]8ddf8322012-02-23 18:08:065521 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365522 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075523 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065524 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365525 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165527
[email protected]49639fa2011-12-20 23:22:415528 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165529
bnc691fda62016-08-12 00:43:165530 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165532
5533 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015534 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165535
ttuttle960fcbf2016-04-19 13:26:325536 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165537}
5538
[email protected]f6c63db52013-02-02 00:35:225539// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5540// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015541TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225542 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5543 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595544 session_deps_.proxy_resolution_service =
5545 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515546 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075547 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095548 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505549 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225550
5551 HttpRequestInfo request1;
5552 request1.method = "GET";
bncce36dca22015-04-21 22:11:235553 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225554 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105555 request1.traffic_annotation =
5556 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225557
5558 HttpRequestInfo request2;
5559 request2.method = "GET";
bncce36dca22015-04-21 22:11:235560 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225561 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105562 request2.traffic_annotation =
5563 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225564
bncce36dca22015-04-21 22:11:235565 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415566 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235567 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155568 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225569
bncce36dca22015-04-21 22:11:235570 // Fetch https://www.example.org/ via HTTP.
5571 const char get1[] =
5572 "GET / HTTP/1.1\r\n"
5573 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225574 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415575 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195576 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225577 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5578 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415579 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195580 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415581 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195582 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415583 SpdySerializedFrame window_update(
5584 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225585
bncce36dca22015-04-21 22:11:235586 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295587 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275588 connect2_block[kHttp2MethodHeader] = "CONNECT";
5589 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155590 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5591 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395592
bnc42331402016-07-25 13:36:155593 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225594
bncce36dca22015-04-21 22:11:235595 // Fetch https://mail.example.org/ via HTTP.
5596 const char get2[] =
5597 "GET / HTTP/1.1\r\n"
5598 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225599 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415600 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195601 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225602 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5603 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415604 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195605 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
bncdf80d44fd2016-07-15 20:27:415606 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195607 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225608
5609 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415610 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5611 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225612 };
5613
5614 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415615 CreateMockRead(conn_resp1, 1, ASYNC),
5616 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5617 CreateMockRead(wrapped_body1, 4, ASYNC),
5618 CreateMockRead(conn_resp2, 6, ASYNC),
5619 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5620 CreateMockRead(wrapped_body2, 9, ASYNC),
5621 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225622 };
5623
mmenke11eb5152015-06-09 14:50:505624 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5625 arraysize(spdy_writes));
5626 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225627
5628 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365629 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225631 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225633 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225635
5636 TestCompletionCallback callback;
5637
bnc691fda62016-08-12 00:43:165638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205639 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015640 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225641
5642 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165643 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225644 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5645
bnc691fda62016-08-12 00:43:165646 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525647 ASSERT_TRUE(response);
5648 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225649 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5650
5651 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295652 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165653 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505654 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225655
bnc691fda62016-08-12 00:43:165656 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205657 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015658 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225659
5660 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165661 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225662 // Even though the SPDY connection is reused, a new tunnelled connection has
5663 // to be created, so the socket's load timing looks like a fresh connection.
5664 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5665
5666 // The requests should have different IDs, since they each are using their own
5667 // separate stream.
5668 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5669
bnc691fda62016-08-12 00:43:165670 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505671 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225672}
5673
5674// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5675// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015676TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225677 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5678 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595679 session_deps_.proxy_resolution_service =
5680 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515681 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075682 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095683 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505684 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225685
5686 HttpRequestInfo request1;
5687 request1.method = "GET";
bncce36dca22015-04-21 22:11:235688 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225689 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105690 request1.traffic_annotation =
5691 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225692
5693 HttpRequestInfo request2;
5694 request2.method = "GET";
bncce36dca22015-04-21 22:11:235695 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225696 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105697 request2.traffic_annotation =
5698 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225699
bncce36dca22015-04-21 22:11:235700 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415701 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235702 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155703 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225704
bncce36dca22015-04-21 22:11:235705 // Fetch https://www.example.org/ via HTTP.
5706 const char get1[] =
5707 "GET / HTTP/1.1\r\n"
5708 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225709 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415710 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195711 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225712 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5713 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415714 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195715 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415716 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195717 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415718 SpdySerializedFrame window_update(
5719 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225720
bncce36dca22015-04-21 22:11:235721 // Fetch https://www.example.org/2 via HTTP.
5722 const char get2[] =
5723 "GET /2 HTTP/1.1\r\n"
5724 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225725 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415726 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195727 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225728 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5729 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415730 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195731 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
bncdf80d44fd2016-07-15 20:27:415732 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195733 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225734
5735 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415736 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5737 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225738 };
5739
5740 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415741 CreateMockRead(conn_resp1, 1, ASYNC),
5742 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465743 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415744 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465745 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415746 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225747 };
5748
mmenke11eb5152015-06-09 14:50:505749 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5750 arraysize(spdy_writes));
5751 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225752
5753 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365754 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225756 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225758
5759 TestCompletionCallback callback;
5760
bnc87dcefc2017-05-25 12:47:585761 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195762 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205763 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225765
5766 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015767 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225768
5769 LoadTimingInfo load_timing_info;
5770 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5771 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5772
5773 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525774 ASSERT_TRUE(response);
5775 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225776 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5777
5778 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295779 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505780 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225781 trans.reset();
5782
bnc87dcefc2017-05-25 12:47:585783 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195784 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205785 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225787
[email protected]f6c63db52013-02-02 00:35:225788 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015789 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225790
5791 LoadTimingInfo load_timing_info2;
5792 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5793 TestLoadTimingReused(load_timing_info2);
5794
5795 // The requests should have the same ID.
5796 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5797
[email protected]90499482013-06-01 00:39:505798 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225799}
5800
5801// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5802// Proxy to different servers.
bncd16676a2016-07-20 16:23:015803TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225804 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595805 session_deps_.proxy_resolution_service =
5806 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515807 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075808 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095809 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505810 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225811
5812 HttpRequestInfo request1;
5813 request1.method = "GET";
bncce36dca22015-04-21 22:11:235814 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225815 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105816 request1.traffic_annotation =
5817 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225818
5819 HttpRequestInfo request2;
5820 request2.method = "GET";
bncce36dca22015-04-21 22:11:235821 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225822 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105823 request2.traffic_annotation =
5824 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225825
bncce36dca22015-04-21 22:11:235826 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265827 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235828 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415829 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155830 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5831 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Bence Békyd74f4382018-02-20 18:26:195832 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385833 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225834
bncce36dca22015-04-21 22:11:235835 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265836 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235837 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415838 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155839 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5840 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
Bence Békyd74f4382018-02-20 18:26:195841 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225842
5843 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415844 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225845 };
5846
5847 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415848 CreateMockRead(get_resp1, 1, ASYNC),
5849 CreateMockRead(body1, 2, ASYNC),
5850 CreateMockRead(get_resp2, 4, ASYNC),
5851 CreateMockRead(body2, 5, ASYNC),
5852 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225853 };
5854
mmenke11eb5152015-06-09 14:50:505855 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5856 arraysize(spdy_writes));
5857 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225858
5859 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365860 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505861 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225862
5863 TestCompletionCallback callback;
5864
bnc87dcefc2017-05-25 12:47:585865 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195866 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205867 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015868 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225869
5870 LoadTimingInfo load_timing_info;
5871 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5872 TestLoadTimingNotReused(load_timing_info,
5873 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5874
5875 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525876 ASSERT_TRUE(response);
5877 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025878 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225879
5880 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295881 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505882 rv = trans->Read(buf.get(), 256, callback.callback());
5883 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225884 // Delete the first request, so the second one can reuse the socket.
5885 trans.reset();
5886
bnc691fda62016-08-12 00:43:165887 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205888 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015889 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225890
5891 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165892 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225893 TestLoadTimingReused(load_timing_info2);
5894
5895 // The requests should have the same ID.
5896 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5897
bnc691fda62016-08-12 00:43:165898 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505899 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225900}
5901
[email protected]2df19bb2010-08-25 20:13:465902// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015903TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465904 HttpRequestInfo request;
5905 request.method = "GET";
bncce36dca22015-04-21 22:11:235906 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465907 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295908 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:105909 request.traffic_annotation =
5910 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465911
[email protected]79cb5c12011-09-12 13:12:045912 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595913 session_deps_.proxy_resolution_service =
5914 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515915 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075916 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275918
[email protected]2df19bb2010-08-25 20:13:465919 // Since we have proxy, should use full url
5920 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165921 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5922 "Host: www.example.org\r\n"
5923 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465924
bnc691fda62016-08-12 00:43:165925 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235926 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165927 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5928 "Host: www.example.org\r\n"
5929 "Proxy-Connection: keep-alive\r\n"
5930 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465931 };
5932
5933 // The proxy responds to the GET with a 407, using a persistent
5934 // connection.
5935 MockRead data_reads1[] = {
5936 // No credentials.
5937 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5938 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5939 MockRead("Proxy-Connection: keep-alive\r\n"),
5940 MockRead("Content-Length: 0\r\n\r\n"),
5941
5942 MockRead("HTTP/1.1 200 OK\r\n"),
5943 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5944 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065945 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465946 };
5947
5948 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5949 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075950 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065951 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075952 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465953
[email protected]49639fa2011-12-20 23:22:415954 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465955
bnc691fda62016-08-12 00:43:165956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505957
bnc691fda62016-08-12 00:43:165958 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465960
5961 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015962 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465963
[email protected]58e32bb2013-01-21 18:23:255964 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165965 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255966 TestLoadTimingNotReused(load_timing_info,
5967 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5968
bnc691fda62016-08-12 00:43:165969 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525970 ASSERT_TRUE(response);
5971 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465972 EXPECT_EQ(407, response->headers->response_code());
5973 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435974 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465975
[email protected]49639fa2011-12-20 23:22:415976 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465977
bnc691fda62016-08-12 00:43:165978 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465980
5981 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015982 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465983
[email protected]58e32bb2013-01-21 18:23:255984 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165985 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255986 // Retrying with HTTP AUTH is considered to be reusing a socket.
5987 TestLoadTimingReused(load_timing_info);
5988
bnc691fda62016-08-12 00:43:165989 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525990 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465991
5992 EXPECT_TRUE(response->headers->IsKeepAlive());
5993 EXPECT_EQ(200, response->headers->response_code());
5994 EXPECT_EQ(100, response->headers->GetContentLength());
5995 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5996
5997 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525998 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465999}
6000
[email protected]23e482282013-06-14 16:08:026001void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086002 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426003 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086004 request.method = "GET";
bncce36dca22015-04-21 22:11:236005 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106006 request.traffic_annotation =
6007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086008
[email protected]cb9bf6ca2011-01-28 13:15:276009 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596010 session_deps_.proxy_resolution_service =
6011 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276013
[email protected]c744cf22009-02-27 07:28:086014 // Since we have proxy, should try to establish tunnel.
6015 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176016 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6017 "Host: www.example.org:443\r\n"
6018 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086019 };
6020
6021 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236022 status, MockRead("Content-Length: 10\r\n\r\n"),
6023 // No response body because the test stops reading here.
6024 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086025 };
6026
[email protected]31a2bfe2010-02-09 08:03:396027 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6028 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076029 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086030
[email protected]49639fa2011-12-20 23:22:416031 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086032
bnc691fda62016-08-12 00:43:166033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506034
tfarina42834112016-09-22 13:38:206035 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016036 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086037
6038 rv = callback.WaitForResult();
6039 EXPECT_EQ(expected_status, rv);
6040}
6041
[email protected]23e482282013-06-14 16:08:026042void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236043 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086044 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426045 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086046}
6047
bncd16676a2016-07-20 16:23:016048TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086049 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6050}
6051
bncd16676a2016-07-20 16:23:016052TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086053 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6054}
6055
bncd16676a2016-07-20 16:23:016056TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086057 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6058}
6059
bncd16676a2016-07-20 16:23:016060TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086061 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6062}
6063
bncd16676a2016-07-20 16:23:016064TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086065 ConnectStatusHelper(
6066 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6067}
6068
bncd16676a2016-07-20 16:23:016069TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086070 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6071}
6072
bncd16676a2016-07-20 16:23:016073TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086074 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6075}
6076
bncd16676a2016-07-20 16:23:016077TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086078 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6079}
6080
bncd16676a2016-07-20 16:23:016081TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086082 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6083}
6084
bncd16676a2016-07-20 16:23:016085TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086086 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6087}
6088
bncd16676a2016-07-20 16:23:016089TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086090 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6091}
6092
bncd16676a2016-07-20 16:23:016093TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086094 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6095}
6096
bncd16676a2016-07-20 16:23:016097TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086098 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6099}
6100
bncd16676a2016-07-20 16:23:016101TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086102 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6103}
6104
bncd16676a2016-07-20 16:23:016105TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086106 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6107}
6108
bncd16676a2016-07-20 16:23:016109TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086110 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6111}
6112
bncd16676a2016-07-20 16:23:016113TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376114 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6115}
6116
bncd16676a2016-07-20 16:23:016117TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086118 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6119}
6120
bncd16676a2016-07-20 16:23:016121TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086122 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6123}
6124
bncd16676a2016-07-20 16:23:016125TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086126 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6127}
6128
bncd16676a2016-07-20 16:23:016129TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086130 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6131}
6132
bncd16676a2016-07-20 16:23:016133TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086134 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6135}
6136
bncd16676a2016-07-20 16:23:016137TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086138 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6139}
6140
bncd16676a2016-07-20 16:23:016141TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086142 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6143}
6144
bncd16676a2016-07-20 16:23:016145TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086146 ConnectStatusHelperWithExpectedStatus(
6147 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546148 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086149}
6150
bncd16676a2016-07-20 16:23:016151TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086152 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6153}
6154
bncd16676a2016-07-20 16:23:016155TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086156 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6157}
6158
bncd16676a2016-07-20 16:23:016159TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086160 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6161}
6162
bncd16676a2016-07-20 16:23:016163TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086164 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6165}
6166
bncd16676a2016-07-20 16:23:016167TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086168 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6169}
6170
bncd16676a2016-07-20 16:23:016171TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086172 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6173}
6174
bncd16676a2016-07-20 16:23:016175TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086176 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6177}
6178
bncd16676a2016-07-20 16:23:016179TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086180 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6181}
6182
bncd16676a2016-07-20 16:23:016183TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086184 ConnectStatusHelper(
6185 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6186}
6187
bncd16676a2016-07-20 16:23:016188TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086189 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6190}
6191
bncd16676a2016-07-20 16:23:016192TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086193 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6194}
6195
bncd16676a2016-07-20 16:23:016196TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086197 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6198}
6199
bncd16676a2016-07-20 16:23:016200TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086201 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6202}
6203
bncd16676a2016-07-20 16:23:016204TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086205 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6206}
6207
bncd16676a2016-07-20 16:23:016208TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086209 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6210}
6211
bncd16676a2016-07-20 16:23:016212TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086213 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6214}
6215
[email protected]038e9a32008-10-08 22:40:166216// Test the flow when both the proxy server AND origin server require
6217// authentication. Again, this uses basic auth for both since that is
6218// the simplest to mock.
bncd16676a2016-07-20 16:23:016219TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276220 HttpRequestInfo request;
6221 request.method = "GET";
bncce36dca22015-04-21 22:11:236222 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106223 request.traffic_annotation =
6224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276225
[email protected]038e9a32008-10-08 22:40:166226 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596227 session_deps_.proxy_resolution_service =
6228 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076230
bnc691fda62016-08-12 00:43:166231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166232
[email protected]f9ee6b52008-11-08 06:46:236233 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236234 MockWrite(
6235 "GET http://www.example.org/ HTTP/1.1\r\n"
6236 "Host: www.example.org\r\n"
6237 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236238 };
6239
[email protected]038e9a32008-10-08 22:40:166240 MockRead data_reads1[] = {
6241 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6242 // Give a couple authenticate options (only the middle one is actually
6243 // supported).
[email protected]22927ad2009-09-21 19:56:196244 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166245 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6246 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6247 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6248 // Large content-length -- won't matter, as connection will be reset.
6249 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066250 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166251 };
6252
bnc691fda62016-08-12 00:43:166253 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166254 // request we should be issuing -- the final header line contains the
6255 // proxy's credentials.
6256 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236257 MockWrite(
6258 "GET http://www.example.org/ HTTP/1.1\r\n"
6259 "Host: www.example.org\r\n"
6260 "Proxy-Connection: keep-alive\r\n"
6261 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166262 };
6263
6264 // Now the proxy server lets the request pass through to origin server.
6265 // The origin server responds with a 401.
6266 MockRead data_reads2[] = {
6267 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6268 // Note: We are using the same realm-name as the proxy server. This is
6269 // completely valid, as realms are unique across hosts.
6270 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6271 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6272 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066273 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166274 };
6275
bnc691fda62016-08-12 00:43:166276 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166277 // the credentials for both the proxy and origin server.
6278 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236279 MockWrite(
6280 "GET http://www.example.org/ HTTP/1.1\r\n"
6281 "Host: www.example.org\r\n"
6282 "Proxy-Connection: keep-alive\r\n"
6283 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6284 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166285 };
6286
6287 // Lastly we get the desired content.
6288 MockRead data_reads3[] = {
6289 MockRead("HTTP/1.0 200 OK\r\n"),
6290 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6291 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066292 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166293 };
6294
[email protected]31a2bfe2010-02-09 08:03:396295 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6296 data_writes1, arraysize(data_writes1));
6297 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6298 data_writes2, arraysize(data_writes2));
6299 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6300 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076301 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6302 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6303 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166304
[email protected]49639fa2011-12-20 23:22:416305 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166306
tfarina42834112016-09-22 13:38:206307 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166309
6310 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016311 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166312
bnc691fda62016-08-12 00:43:166313 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526314 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046315 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166316
[email protected]49639fa2011-12-20 23:22:416317 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166318
bnc691fda62016-08-12 00:43:166319 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016320 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166321
6322 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016323 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166324
bnc691fda62016-08-12 00:43:166325 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526326 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046327 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166328
[email protected]49639fa2011-12-20 23:22:416329 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166330
bnc691fda62016-08-12 00:43:166331 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6332 callback3.callback());
robpercival214763f2016-07-01 23:27:016333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166334
6335 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016336 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166337
bnc691fda62016-08-12 00:43:166338 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526339 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166340 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166341}
[email protected]4ddaf2502008-10-23 18:26:196342
[email protected]ea9dc9a2009-09-05 00:43:326343// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6344// can't hook into its internals to cause it to generate predictable NTLM
6345// authorization headers.
6346#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376347// The NTLM authentication unit tests are based on known test data from the
6348// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6349// flow rather than the implementation of the NTLM protocol. See net/ntlm
6350// for the implementation and testing of the protocol.
6351//
6352// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296353
6354// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556355TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426356 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246357 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556358 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106359 request.traffic_annotation =
6360 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546361
6362 // Ensure load is not disrupted by flags which suppress behaviour specific
6363 // to other auth schemes.
6364 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246365
Zentaro Kavanagh6ccee512017-09-28 18:34:096366 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6367 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276369
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376370 // Generate the NTLM messages based on known test data.
6371 std::string negotiate_msg;
6372 std::string challenge_msg;
6373 std::string authenticate_msg;
6374 base::Base64Encode(
6375 base::StringPiece(
6376 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6377 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6378 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556379 base::Base64Encode(
6380 base::StringPiece(
6381 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6382 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6383 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376384 base::Base64Encode(
6385 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096386 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556387 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6388 arraysize(
6389 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376390 &authenticate_msg);
6391
[email protected]3f918782009-02-28 01:29:246392 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556393 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6394 "Host: server\r\n"
6395 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246396 };
6397
6398 MockRead data_reads1[] = {
6399 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046400 // Negotiate and NTLM are often requested together. However, we only want
6401 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6402 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246403 MockRead("WWW-Authenticate: NTLM\r\n"),
6404 MockRead("Connection: close\r\n"),
6405 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366406 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246407 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246408 };
6409
6410 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166411 // After restarting with a null identity, this is the
6412 // request we should be issuing -- the final header line contains a Type
6413 // 1 message.
6414 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556415 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166416 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376417 "Authorization: NTLM "),
6418 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246419
bnc691fda62016-08-12 00:43:166420 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376421 // (using correct credentials). The second request continues on the
6422 // same connection.
bnc691fda62016-08-12 00:43:166423 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(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246428 };
6429
6430 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026431 // The origin server responds with a Type 2 message.
6432 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376433 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6434 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026435 MockRead("Content-Type: text/html\r\n\r\n"),
6436 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246437
Bence Béky1e4ef192017-09-18 19:58:026438 // Lastly we get the desired content.
6439 MockRead("HTTP/1.1 200 OK\r\n"),
6440 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6441 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246442 };
6443
[email protected]31a2bfe2010-02-09 08:03:396444 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6445 data_writes1, arraysize(data_writes1));
6446 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6447 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076448 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6449 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246450
Bence Béky83eb3512017-09-05 12:56:096451 SSLSocketDataProvider ssl1(ASYNC, OK);
6452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6453 SSLSocketDataProvider ssl2(ASYNC, OK);
6454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6455
[email protected]49639fa2011-12-20 23:22:416456 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246457
bnc691fda62016-08-12 00:43:166458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506459
tfarina42834112016-09-22 13:38:206460 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246462
6463 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016464 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246465
bnc691fda62016-08-12 00:43:166466 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226467
bnc691fda62016-08-12 00:43:166468 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526469 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046470 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246471
[email protected]49639fa2011-12-20 23:22:416472 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256473
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376474 rv = trans.RestartWithAuth(
6475 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6476 callback2.callback());
robpercival214763f2016-07-01 23:27:016477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256478
6479 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016480 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256481
bnc691fda62016-08-12 00:43:166482 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256483
bnc691fda62016-08-12 00:43:166484 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526485 ASSERT_TRUE(response);
6486 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256487
[email protected]49639fa2011-12-20 23:22:416488 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246489
bnc691fda62016-08-12 00:43:166490 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246492
[email protected]0757e7702009-03-27 04:00:226493 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016494 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246495
bnc691fda62016-08-12 00:43:166496 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526497 ASSERT_TRUE(response);
6498 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026499 EXPECT_EQ(14, response->headers->GetContentLength());
6500
6501 std::string response_data;
6502 rv = ReadTransaction(&trans, &response_data);
6503 EXPECT_THAT(rv, IsOk());
6504 EXPECT_EQ("Please Login\r\n", response_data);
6505
6506 EXPECT_TRUE(data1.AllReadDataConsumed());
6507 EXPECT_TRUE(data1.AllWriteDataConsumed());
6508 EXPECT_TRUE(data2.AllReadDataConsumed());
6509 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246510}
6511
[email protected]385a4672009-03-11 22:21:296512// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556513TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426514 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296515 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556516 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106517 request.traffic_annotation =
6518 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296519
Zentaro Kavanagh6ccee512017-09-28 18:34:096520 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6521 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096522 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276523
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376524 // Generate the NTLM messages based on known test data.
6525 std::string negotiate_msg;
6526 std::string challenge_msg;
6527 std::string authenticate_msg;
6528 base::Base64Encode(
6529 base::StringPiece(
6530 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6531 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6532 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556533 base::Base64Encode(
6534 base::StringPiece(
6535 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6536 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6537 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376538 base::Base64Encode(
6539 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096540 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556541 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6542 arraysize(
6543 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376544 &authenticate_msg);
6545
6546 // The authenticate message when |kWrongPassword| is sent.
6547 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556548 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6549 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6550 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6551 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6552 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6553 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376554
Zentaro Kavanagh1890a3d2018-01-29 19:52:556555 // Sanity check that it's the same length as the correct authenticate message
6556 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376557 ASSERT_EQ(authenticate_msg.length(),
6558 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556559 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376560
[email protected]385a4672009-03-11 22:21:296561 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556562 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6563 "Host: server\r\n"
6564 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296565 };
6566
6567 MockRead data_reads1[] = {
6568 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046569 // Negotiate and NTLM are often requested together. However, we only want
6570 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6571 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296572 MockRead("WWW-Authenticate: NTLM\r\n"),
6573 MockRead("Connection: close\r\n"),
6574 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366575 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296576 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296577 };
6578
6579 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166580 // After restarting with a null identity, this is the
6581 // request we should be issuing -- the final header line contains a Type
6582 // 1 message.
6583 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556584 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166585 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376586 "Authorization: NTLM "),
6587 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296588
bnc691fda62016-08-12 00:43:166589 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376590 // (using incorrect credentials). The second request continues on the
6591 // same connection.
bnc691fda62016-08-12 00:43:166592 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(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296597 };
6598
6599 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376600 // The origin server responds with a Type 2 message.
6601 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6602 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6603 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6604 MockRead("Content-Type: text/html\r\n\r\n"),
6605 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296606
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376607 // Wrong password.
6608 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6609 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6610 MockRead("Content-Length: 42\r\n"),
6611 MockRead("Content-Type: text/html\r\n\r\n"),
6612 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296613 };
6614
6615 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166616 // After restarting with a null identity, this is the
6617 // request we should be issuing -- the final header line contains a Type
6618 // 1 message.
6619 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556620 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166621 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376622 "Authorization: NTLM "),
6623 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296624
bnc691fda62016-08-12 00:43:166625 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6626 // (the credentials for the origin server). The second request continues
6627 // on the same connection.
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(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296633 };
6634
6635 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026636 // The origin server responds with a Type 2 message.
6637 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376638 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6639 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026640 MockRead("Content-Type: text/html\r\n\r\n"),
6641 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296642
Bence Béky1e4ef192017-09-18 19:58:026643 // Lastly we get the desired content.
6644 MockRead("HTTP/1.1 200 OK\r\n"),
6645 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6646 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296647 };
6648
[email protected]31a2bfe2010-02-09 08:03:396649 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6650 data_writes1, arraysize(data_writes1));
6651 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6652 data_writes2, arraysize(data_writes2));
6653 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6654 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076655 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6656 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6657 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296658
Bence Béky83eb3512017-09-05 12:56:096659 SSLSocketDataProvider ssl1(ASYNC, OK);
6660 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6661 SSLSocketDataProvider ssl2(ASYNC, OK);
6662 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6663 SSLSocketDataProvider ssl3(ASYNC, OK);
6664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6665
[email protected]49639fa2011-12-20 23:22:416666 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296667
bnc691fda62016-08-12 00:43:166668 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506669
tfarina42834112016-09-22 13:38:206670 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016671 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296672
6673 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016674 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296675
bnc691fda62016-08-12 00:43:166676 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296677
bnc691fda62016-08-12 00:43:166678 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526679 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046680 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296681
[email protected]49639fa2011-12-20 23:22:416682 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296683
[email protected]0757e7702009-03-27 04:00:226684 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376685 rv = trans.RestartWithAuth(
6686 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6687 callback2.callback());
robpercival214763f2016-07-01 23:27:016688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296689
[email protected]10af5fe72011-01-31 16:17:256690 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016691 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296692
bnc691fda62016-08-12 00:43:166693 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416694 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166695 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256697 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016698 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166699 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226700
bnc691fda62016-08-12 00:43:166701 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526702 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046703 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226704
[email protected]49639fa2011-12-20 23:22:416705 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226706
6707 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376708 rv = trans.RestartWithAuth(
6709 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6710 callback4.callback());
robpercival214763f2016-07-01 23:27:016711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256712
6713 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016714 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256715
bnc691fda62016-08-12 00:43:166716 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256717
[email protected]49639fa2011-12-20 23:22:416718 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256719
6720 // One more roundtrip
bnc691fda62016-08-12 00:43:166721 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016722 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226723
6724 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016725 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226726
bnc691fda62016-08-12 00:43:166727 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526728 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026729 EXPECT_EQ(14, response->headers->GetContentLength());
6730
6731 std::string response_data;
6732 rv = ReadTransaction(&trans, &response_data);
6733 EXPECT_THAT(rv, IsOk());
6734 EXPECT_EQ("Please Login\r\n", response_data);
6735
6736 EXPECT_TRUE(data1.AllReadDataConsumed());
6737 EXPECT_TRUE(data1.AllWriteDataConsumed());
6738 EXPECT_TRUE(data2.AllReadDataConsumed());
6739 EXPECT_TRUE(data2.AllWriteDataConsumed());
6740 EXPECT_TRUE(data3.AllReadDataConsumed());
6741 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296742}
Bence Béky83eb3512017-09-05 12:56:096743
Bence Béky3238f2e12017-09-22 22:44:496744// Server requests NTLM authentication, which is not supported over HTTP/2.
6745// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096746TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096747 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6748 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096749
Zentaro Kavanagh1890a3d2018-01-29 19:52:556750 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096751
6752 HttpRequestInfo request;
6753 request.method = "GET";
6754 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:106755 request.traffic_annotation =
6756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096757
6758 // First request without credentials.
6759 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6760 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6761 1, std::move(request_headers0), LOWEST, true));
6762
6763 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276764 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096765 response_headers0["www-authenticate"] = "NTLM";
6766 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6767 1, std::move(response_headers0), true));
6768
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376769 // Stream 1 is closed.
6770 spdy_util_.UpdateWithStreamDestruction(1);
6771
6772 // Generate the NTLM messages based on known test data.
6773 std::string negotiate_msg;
6774 std::string challenge_msg;
6775 std::string authenticate_msg;
6776 base::Base64Encode(
6777 base::StringPiece(
6778 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6779 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6780 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556781 base::Base64Encode(
6782 base::StringPiece(
6783 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6784 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6785 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376786 base::Base64Encode(
6787 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096788 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556789 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6790 arraysize(
6791 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376792 &authenticate_msg);
6793
6794 // Retry with authorization header.
6795 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6796 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6797 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6798 3, std::move(request_headers1), LOWEST, true));
6799
6800 SpdySerializedFrame rst(
6801 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6802
Bence Béky3238f2e12017-09-22 22:44:496803 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6804 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096805
6806 // Retry yet again using HTTP/1.1.
6807 MockWrite writes1[] = {
6808 // After restarting with a null identity, this is the
6809 // request we should be issuing -- the final header line contains a Type
6810 // 1 message.
6811 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556812 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096813 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376814 "Authorization: NTLM "),
6815 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096816
6817 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6818 // (the credentials for the origin server). The second request continues
6819 // on the same connection.
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(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096825 };
6826
6827 MockRead reads1[] = {
6828 // The origin server responds with a Type 2 message.
6829 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376830 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6831 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096832 MockRead("Content-Type: text/html\r\n\r\n"),
6833 MockRead("You are not authorized to view this page\r\n"),
6834
6835 // Lastly we get the desired content.
6836 MockRead("HTTP/1.1 200 OK\r\n"),
6837 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026838 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096839 };
6840 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6841 arraysize(writes0));
6842 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6843 arraysize(writes1));
6844 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6845 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6846
6847 SSLSocketDataProvider ssl0(ASYNC, OK);
6848 ssl0.next_proto = kProtoHTTP2;
6849 SSLSocketDataProvider ssl1(ASYNC, OK);
6850 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6851 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6852
6853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6855
6856 TestCompletionCallback callback1;
6857 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6859
6860 rv = callback1.WaitForResult();
6861 EXPECT_THAT(rv, IsOk());
6862
6863 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6864
6865 const HttpResponseInfo* response = trans.GetResponseInfo();
6866 ASSERT_TRUE(response);
6867 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6868
6869 TestCompletionCallback callback2;
6870
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376871 rv = trans.RestartWithAuth(
6872 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6873 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6875
6876 rv = callback2.WaitForResult();
6877 EXPECT_THAT(rv, IsOk());
6878
6879 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6880
6881 response = trans.GetResponseInfo();
6882 ASSERT_TRUE(response);
6883 EXPECT_FALSE(response->auth_challenge);
6884
6885 TestCompletionCallback callback3;
6886
6887 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6889
6890 rv = callback3.WaitForResult();
6891 EXPECT_THAT(rv, IsOk());
6892
6893 response = trans.GetResponseInfo();
6894 ASSERT_TRUE(response);
6895 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026896 EXPECT_EQ(14, response->headers->GetContentLength());
6897
6898 std::string response_data;
6899 rv = ReadTransaction(&trans, &response_data);
6900 EXPECT_THAT(rv, IsOk());
6901 EXPECT_EQ("Please Login\r\n", response_data);
6902
6903 EXPECT_TRUE(data0.AllReadDataConsumed());
6904 EXPECT_TRUE(data0.AllWriteDataConsumed());
6905 EXPECT_TRUE(data1.AllReadDataConsumed());
6906 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096907}
[email protected]ea9dc9a2009-09-05 00:43:326908#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296909
[email protected]4ddaf2502008-10-23 18:26:196910// Test reading a server response which has only headers, and no body.
6911// After some maximum number of bytes is consumed, the transaction should
6912// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016913TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426914 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196915 request.method = "GET";
bncce36dca22015-04-21 22:11:236916 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106917 request.traffic_annotation =
6918 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196919
danakj1fd259a02016-04-16 03:17:096920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166921 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276922
[email protected]b75b7b2f2009-10-06 00:54:536923 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436924 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536925 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196926
6927 MockRead data_reads[] = {
6928 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066929 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196930 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066931 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196932 };
[email protected]31a2bfe2010-02-09 08:03:396933 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076934 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196935
[email protected]49639fa2011-12-20 23:22:416936 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196937
tfarina42834112016-09-22 13:38:206938 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196940
6941 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016942 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196943}
[email protected]f4e426b2008-11-05 00:24:496944
6945// Make sure that we don't try to reuse a TCPClientSocket when failing to
6946// establish tunnel.
6947// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016948TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276949 HttpRequestInfo request;
6950 request.method = "GET";
bncce36dca22015-04-21 22:11:236951 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106952 request.traffic_annotation =
6953 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276954
[email protected]f4e426b2008-11-05 00:24:496955 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596956 session_deps_.proxy_resolution_service =
6957 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016958
danakj1fd259a02016-04-16 03:17:096959 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496960
bnc87dcefc2017-05-25 12:47:586961 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196962 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496963
[email protected]f4e426b2008-11-05 00:24:496964 // Since we have proxy, should try to establish tunnel.
6965 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176966 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6967 "Host: www.example.org:443\r\n"
6968 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496969 };
6970
[email protected]77848d12008-11-14 00:00:226971 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496972 // connection. Usually a proxy would return 501 (not implemented),
6973 // or 200 (tunnel established).
6974 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236975 MockRead("HTTP/1.1 404 Not Found\r\n"),
6976 MockRead("Content-Length: 10\r\n\r\n"),
6977 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496978 };
6979
[email protected]31a2bfe2010-02-09 08:03:396980 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6981 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076982 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496983
[email protected]49639fa2011-12-20 23:22:416984 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496985
tfarina42834112016-09-22 13:38:206986 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016987 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496988
6989 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016990 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496991
[email protected]b4404c02009-04-10 16:38:526992 // Empty the current queue. This is necessary because idle sockets are
6993 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556994 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526995
[email protected]f4e426b2008-11-05 00:24:496996 // We now check to make sure the TCPClientSocket was not added back to
6997 // the pool.
[email protected]90499482013-06-01 00:39:506998 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496999 trans.reset();
fdoray92e35a72016-06-10 15:54:557000 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497001 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507002 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497003}
[email protected]372d34a2008-11-05 21:30:517004
[email protected]1b157c02009-04-21 01:55:407005// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017006TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427007 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407008 request.method = "GET";
bncce36dca22015-04-21 22:11:237009 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107010 request.traffic_annotation =
7011 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407012
danakj1fd259a02016-04-16 03:17:097013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277014
bnc691fda62016-08-12 00:43:167015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277016
[email protected]1b157c02009-04-21 01:55:407017 MockRead data_reads[] = {
7018 // A part of the response body is received with the response headers.
7019 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7020 // The rest of the response body is received in two parts.
7021 MockRead("lo"),
7022 MockRead(" world"),
7023 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067024 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407025 };
7026
[email protected]31a2bfe2010-02-09 08:03:397027 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077028 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407029
[email protected]49639fa2011-12-20 23:22:417030 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407031
tfarina42834112016-09-22 13:38:207032 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407034
7035 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017036 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407037
bnc691fda62016-08-12 00:43:167038 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527039 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407040
wezca1070932016-05-26 20:30:527041 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407042 std::string status_line = response->headers->GetStatusLine();
7043 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7044
[email protected]90499482013-06-01 00:39:507045 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407046
7047 std::string response_data;
bnc691fda62016-08-12 00:43:167048 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017049 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407050 EXPECT_EQ("hello world", response_data);
7051
7052 // Empty the current queue. This is necessary because idle sockets are
7053 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557054 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407055
7056 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507057 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407058}
7059
[email protected]76a505b2010-08-25 06:23:007060// Make sure that we recycle a SSL socket after reading all of the response
7061// body.
bncd16676a2016-07-20 16:23:017062TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007063 HttpRequestInfo request;
7064 request.method = "GET";
bncce36dca22015-04-21 22:11:237065 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107066 request.traffic_annotation =
7067 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007068
7069 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237070 MockWrite(
7071 "GET / HTTP/1.1\r\n"
7072 "Host: www.example.org\r\n"
7073 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007074 };
7075
7076 MockRead data_reads[] = {
7077 MockRead("HTTP/1.1 200 OK\r\n"),
7078 MockRead("Content-Length: 11\r\n\r\n"),
7079 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067080 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007081 };
7082
[email protected]8ddf8322012-02-23 18:08:067083 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077084 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007085
7086 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7087 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077088 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007089
[email protected]49639fa2011-12-20 23:22:417090 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007091
danakj1fd259a02016-04-16 03:17:097092 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167093 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007094
tfarina42834112016-09-22 13:38:207095 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007096
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7098 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007099
bnc691fda62016-08-12 00:43:167100 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527101 ASSERT_TRUE(response);
7102 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007103 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7104
[email protected]90499482013-06-01 00:39:507105 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007106
7107 std::string response_data;
bnc691fda62016-08-12 00:43:167108 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017109 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007110 EXPECT_EQ("hello world", response_data);
7111
7112 // Empty the current queue. This is necessary because idle sockets are
7113 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557114 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007115
7116 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507117 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007118}
7119
7120// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7121// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017122TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007123 HttpRequestInfo request;
7124 request.method = "GET";
bncce36dca22015-04-21 22:11:237125 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107126 request.traffic_annotation =
7127 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007128
7129 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237130 MockWrite(
7131 "GET / HTTP/1.1\r\n"
7132 "Host: www.example.org\r\n"
7133 "Connection: keep-alive\r\n\r\n"),
7134 MockWrite(
7135 "GET / HTTP/1.1\r\n"
7136 "Host: www.example.org\r\n"
7137 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007138 };
7139
7140 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427141 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7142 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007143
[email protected]8ddf8322012-02-23 18:08:067144 SSLSocketDataProvider ssl(ASYNC, OK);
7145 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007148
7149 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7150 data_writes, arraysize(data_writes));
7151 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7152 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077153 session_deps_.socket_factory->AddSocketDataProvider(&data);
7154 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007155
[email protected]49639fa2011-12-20 23:22:417156 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007157
danakj1fd259a02016-04-16 03:17:097158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587159 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197160 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007161
tfarina42834112016-09-22 13:38:207162 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007163
robpercival214763f2016-07-01 23:27:017164 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7165 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007166
7167 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527168 ASSERT_TRUE(response);
7169 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007170 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7171
[email protected]90499482013-06-01 00:39:507172 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007173
7174 std::string response_data;
7175 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017176 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007177 EXPECT_EQ("hello world", response_data);
7178
7179 // Empty the current queue. This is necessary because idle sockets are
7180 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557181 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007182
7183 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507184 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007185
7186 // Now start the second transaction, which should reuse the previous socket.
7187
bnc87dcefc2017-05-25 12:47:587188 trans =
Jeremy Roman0579ed62017-08-29 15:56:197189 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007190
tfarina42834112016-09-22 13:38:207191 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007192
robpercival214763f2016-07-01 23:27:017193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7194 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007195
7196 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527197 ASSERT_TRUE(response);
7198 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007199 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7200
[email protected]90499482013-06-01 00:39:507201 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007202
7203 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017204 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007205 EXPECT_EQ("hello world", response_data);
7206
7207 // Empty the current queue. This is necessary because idle sockets are
7208 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557209 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007210
7211 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507212 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007213}
7214
maksim.sisov0adf8592016-07-15 06:25:567215// Grab a socket, use it, and put it back into the pool. Then, make
7216// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017217TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567218 HttpRequestInfo request;
7219 request.method = "GET";
7220 request.url = GURL("http://www.example.org/");
7221 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107222 request.traffic_annotation =
7223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567224
7225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7226
bnc691fda62016-08-12 00:43:167227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567228
7229 MockRead data_reads[] = {
7230 // A part of the response body is received with the response headers.
7231 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7232 // The rest of the response body is received in two parts.
7233 MockRead("lo"), MockRead(" world"),
7234 MockRead("junk"), // Should not be read!!
7235 MockRead(SYNCHRONOUS, OK),
7236 };
7237
7238 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7239 session_deps_.socket_factory->AddSocketDataProvider(&data);
7240
7241 TestCompletionCallback callback;
7242
tfarina42834112016-09-22 13:38:207243 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7245
7246 EXPECT_THAT(callback.GetResult(rv), IsOk());
7247
bnc691fda62016-08-12 00:43:167248 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567249 ASSERT_TRUE(response);
7250 EXPECT_TRUE(response->headers);
7251 std::string status_line = response->headers->GetStatusLine();
7252 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7253
7254 // Make memory critical notification and ensure the transaction still has been
7255 // operating right.
7256 base::MemoryPressureListener::NotifyMemoryPressure(
7257 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7258 base::RunLoop().RunUntilIdle();
7259
7260 // Socket should not be flushed as long as it is not idle.
7261 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7262
7263 std::string response_data;
bnc691fda62016-08-12 00:43:167264 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567265 EXPECT_THAT(rv, IsOk());
7266 EXPECT_EQ("hello world", response_data);
7267
7268 // Empty the current queue. This is necessary because idle sockets are
7269 // added to the connection pool asynchronously with a PostTask.
7270 base::RunLoop().RunUntilIdle();
7271
7272 // We now check to make sure the socket was added back to the pool.
7273 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7274
7275 // Idle sockets should be flushed now.
7276 base::MemoryPressureListener::NotifyMemoryPressure(
7277 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7278 base::RunLoop().RunUntilIdle();
7279
7280 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7281}
7282
yucliu48f235d2018-01-11 00:59:557283// Disable idle socket closing on memory pressure.
7284// Grab a socket, use it, and put it back into the pool. Then, make
7285// low memory notification and ensure the socket pool is NOT flushed.
7286TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7287 HttpRequestInfo request;
7288 request.method = "GET";
7289 request.url = GURL("http://www.example.org/");
7290 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107291 request.traffic_annotation =
7292 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557293
7294 // Disable idle socket closing on memory pressure.
7295 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7296 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7297
7298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7299
7300 MockRead data_reads[] = {
7301 // A part of the response body is received with the response headers.
7302 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7303 // The rest of the response body is received in two parts.
7304 MockRead("lo"), MockRead(" world"),
7305 MockRead("junk"), // Should not be read!!
7306 MockRead(SYNCHRONOUS, OK),
7307 };
7308
7309 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7310 session_deps_.socket_factory->AddSocketDataProvider(&data);
7311
7312 TestCompletionCallback callback;
7313
7314 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7316
7317 EXPECT_THAT(callback.GetResult(rv), IsOk());
7318
7319 const HttpResponseInfo* response = trans.GetResponseInfo();
7320 ASSERT_TRUE(response);
7321 EXPECT_TRUE(response->headers);
7322 std::string status_line = response->headers->GetStatusLine();
7323 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7324
7325 // Make memory critical notification and ensure the transaction still has been
7326 // operating right.
7327 base::MemoryPressureListener::NotifyMemoryPressure(
7328 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7329 base::RunLoop().RunUntilIdle();
7330
7331 // Socket should not be flushed as long as it is not idle.
7332 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7333
7334 std::string response_data;
7335 rv = ReadTransaction(&trans, &response_data);
7336 EXPECT_THAT(rv, IsOk());
7337 EXPECT_EQ("hello world", response_data);
7338
7339 // Empty the current queue. This is necessary because idle sockets are
7340 // added to the connection pool asynchronously with a PostTask.
7341 base::RunLoop().RunUntilIdle();
7342
7343 // We now check to make sure the socket was added back to the pool.
7344 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7345
7346 // Idle sockets should NOT be flushed on moderate memory pressure.
7347 base::MemoryPressureListener::NotifyMemoryPressure(
7348 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7349 base::RunLoop().RunUntilIdle();
7350
7351 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7352
7353 // Idle sockets should NOT be flushed on critical memory pressure.
7354 base::MemoryPressureListener::NotifyMemoryPressure(
7355 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7356 base::RunLoop().RunUntilIdle();
7357
7358 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7359}
7360
maksim.sisov0adf8592016-07-15 06:25:567361// Grab an SSL socket, use it, and put it back into the pool. Then, make
7362// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017363TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567364 HttpRequestInfo request;
7365 request.method = "GET";
7366 request.url = GURL("https://www.example.org/");
7367 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107368 request.traffic_annotation =
7369 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567370
7371 MockWrite data_writes[] = {
7372 MockWrite("GET / HTTP/1.1\r\n"
7373 "Host: www.example.org\r\n"
7374 "Connection: keep-alive\r\n\r\n"),
7375 };
7376
7377 MockRead data_reads[] = {
7378 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7379 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7380
7381 SSLSocketDataProvider ssl(ASYNC, OK);
7382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7383
7384 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7385 arraysize(data_writes));
7386 session_deps_.socket_factory->AddSocketDataProvider(&data);
7387
7388 TestCompletionCallback callback;
7389
7390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167391 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567392
7393 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207394 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567395
7396 EXPECT_THAT(callback.GetResult(rv), IsOk());
7397
bnc691fda62016-08-12 00:43:167398 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567399 ASSERT_TRUE(response);
7400 ASSERT_TRUE(response->headers);
7401 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7402
7403 // Make memory critical notification and ensure the transaction still has been
7404 // operating right.
7405 base::MemoryPressureListener::NotifyMemoryPressure(
7406 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7407 base::RunLoop().RunUntilIdle();
7408
7409 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7410
7411 std::string response_data;
bnc691fda62016-08-12 00:43:167412 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567413 EXPECT_THAT(rv, IsOk());
7414 EXPECT_EQ("hello world", response_data);
7415
7416 // Empty the current queue. This is necessary because idle sockets are
7417 // added to the connection pool asynchronously with a PostTask.
7418 base::RunLoop().RunUntilIdle();
7419
7420 // We now check to make sure the socket was added back to the pool.
7421 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7422
7423 // Make memory notification once again and ensure idle socket is closed.
7424 base::MemoryPressureListener::NotifyMemoryPressure(
7425 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7426 base::RunLoop().RunUntilIdle();
7427
7428 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7429}
7430
[email protected]b4404c02009-04-10 16:38:527431// Make sure that we recycle a socket after a zero-length response.
7432// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017433TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427434 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527435 request.method = "GET";
bncce36dca22015-04-21 22:11:237436 request.url = GURL(
7437 "http://www.example.org/csi?v=3&s=web&action=&"
7438 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7439 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7440 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:107441 request.traffic_annotation =
7442 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527443
danakj1fd259a02016-04-16 03:17:097444 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277445
[email protected]b4404c02009-04-10 16:38:527446 MockRead data_reads[] = {
7447 MockRead("HTTP/1.1 204 No Content\r\n"
7448 "Content-Length: 0\r\n"
7449 "Content-Type: text/html\r\n\r\n"),
7450 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067451 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527452 };
7453
[email protected]31a2bfe2010-02-09 08:03:397454 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077455 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527456
mmenkecc2298e2015-12-07 18:20:187457 // Transaction must be created after the MockReads, so it's destroyed before
7458 // them.
bnc691fda62016-08-12 00:43:167459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187460
[email protected]49639fa2011-12-20 23:22:417461 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527462
tfarina42834112016-09-22 13:38:207463 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527465
7466 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017467 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527468
bnc691fda62016-08-12 00:43:167469 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527470 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527471
wezca1070932016-05-26 20:30:527472 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527473 std::string status_line = response->headers->GetStatusLine();
7474 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7475
[email protected]90499482013-06-01 00:39:507476 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527477
7478 std::string response_data;
bnc691fda62016-08-12 00:43:167479 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017480 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527481 EXPECT_EQ("", response_data);
7482
7483 // Empty the current queue. This is necessary because idle sockets are
7484 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557485 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527486
7487 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507488 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527489}
7490
bncd16676a2016-07-20 16:23:017491TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097492 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227493 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197494 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227495 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277496
[email protected]1c773ea12009-04-28 19:58:427497 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517498 // Transaction 1: a GET request that succeeds. The socket is recycled
7499 // after use.
7500 request[0].method = "GET";
7501 request[0].url = GURL("http://www.google.com/");
7502 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107503 request[0].traffic_annotation =
7504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517505 // Transaction 2: a POST request. Reuses the socket kept alive from
7506 // transaction 1. The first attempts fails when writing the POST data.
7507 // This causes the transaction to retry with a new socket. The second
7508 // attempt succeeds.
7509 request[1].method = "POST";
7510 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277511 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517512 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107513 request[1].traffic_annotation =
7514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517515
danakj1fd259a02016-04-16 03:17:097516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517517
7518 // The first socket is used for transaction 1 and the first attempt of
7519 // transaction 2.
7520
7521 // The response of transaction 1.
7522 MockRead data_reads1[] = {
7523 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7524 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067525 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517526 };
7527 // The mock write results of transaction 1 and the first attempt of
7528 // transaction 2.
7529 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067530 MockWrite(SYNCHRONOUS, 64), // GET
7531 MockWrite(SYNCHRONOUS, 93), // POST
7532 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517533 };
[email protected]31a2bfe2010-02-09 08:03:397534 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7535 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517536
7537 // The second socket is used for the second attempt of transaction 2.
7538
7539 // The response of transaction 2.
7540 MockRead data_reads2[] = {
7541 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7542 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067543 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517544 };
7545 // The mock write results of the second attempt of transaction 2.
7546 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067547 MockWrite(SYNCHRONOUS, 93), // POST
7548 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517549 };
[email protected]31a2bfe2010-02-09 08:03:397550 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7551 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517552
[email protected]bb88e1d32013-05-03 23:11:077553 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517555
thestig9d3bb0c2015-01-24 00:49:517556 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517557 "hello world", "welcome"
7558 };
7559
7560 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167561 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517562
[email protected]49639fa2011-12-20 23:22:417563 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517564
tfarina42834112016-09-22 13:38:207565 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517567
7568 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017569 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517570
bnc691fda62016-08-12 00:43:167571 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527572 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517573
wezca1070932016-05-26 20:30:527574 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517575 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7576
7577 std::string response_data;
bnc691fda62016-08-12 00:43:167578 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017579 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517580 EXPECT_EQ(kExpectedResponseData[i], response_data);
7581 }
7582}
[email protected]f9ee6b52008-11-08 06:46:237583
7584// Test the request-challenge-retry sequence for basic auth when there is
7585// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167586// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017587TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427588 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237589 request.method = "GET";
bncce36dca22015-04-21 22:11:237590 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417591 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107592 request.traffic_annotation =
7593 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297594
danakj1fd259a02016-04-16 03:17:097595 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167596 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277597
[email protected]a97cca42009-08-14 01:00:297598 // The password contains an escaped character -- for this test to pass it
7599 // will need to be unescaped by HttpNetworkTransaction.
7600 EXPECT_EQ("b%40r", request.url.password());
7601
[email protected]f9ee6b52008-11-08 06:46:237602 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237603 MockWrite(
7604 "GET / HTTP/1.1\r\n"
7605 "Host: www.example.org\r\n"
7606 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237607 };
7608
7609 MockRead data_reads1[] = {
7610 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7611 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7612 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067613 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237614 };
7615
[email protected]2262e3a2012-05-22 16:08:167616 // After the challenge above, the transaction will be restarted using the
7617 // identity from the url (foo, b@r) to answer the challenge.
7618 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237619 MockWrite(
7620 "GET / HTTP/1.1\r\n"
7621 "Host: www.example.org\r\n"
7622 "Connection: keep-alive\r\n"
7623 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167624 };
7625
7626 MockRead data_reads2[] = {
7627 MockRead("HTTP/1.0 200 OK\r\n"),
7628 MockRead("Content-Length: 100\r\n\r\n"),
7629 MockRead(SYNCHRONOUS, OK),
7630 };
7631
[email protected]31a2bfe2010-02-09 08:03:397632 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7633 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167634 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7635 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077636 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7637 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237638
[email protected]49639fa2011-12-20 23:22:417639 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207640 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237642 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017643 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167644 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167645
7646 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167647 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167649 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017650 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167651 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227652
bnc691fda62016-08-12 00:43:167653 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527654 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167655
7656 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527657 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167658
7659 EXPECT_EQ(100, response->headers->GetContentLength());
7660
7661 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557662 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167663}
7664
7665// Test the request-challenge-retry sequence for basic auth when there is an
7666// incorrect identity in the URL. The identity from the URL should be used only
7667// once.
bncd16676a2016-07-20 16:23:017668TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167669 HttpRequestInfo request;
7670 request.method = "GET";
7671 // Note: the URL has a username:password in it. The password "baz" is
7672 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237673 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167674
7675 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107676 request.traffic_annotation =
7677 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167678
danakj1fd259a02016-04-16 03:17:097679 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167681
7682 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237683 MockWrite(
7684 "GET / HTTP/1.1\r\n"
7685 "Host: www.example.org\r\n"
7686 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167687 };
7688
7689 MockRead data_reads1[] = {
7690 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7691 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7692 MockRead("Content-Length: 10\r\n\r\n"),
7693 MockRead(SYNCHRONOUS, ERR_FAILED),
7694 };
7695
7696 // After the challenge above, the transaction will be restarted using the
7697 // identity from the url (foo, baz) to answer the challenge.
7698 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237699 MockWrite(
7700 "GET / HTTP/1.1\r\n"
7701 "Host: www.example.org\r\n"
7702 "Connection: keep-alive\r\n"
7703 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167704 };
7705
7706 MockRead data_reads2[] = {
7707 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7708 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7709 MockRead("Content-Length: 10\r\n\r\n"),
7710 MockRead(SYNCHRONOUS, ERR_FAILED),
7711 };
7712
7713 // After the challenge above, the transaction will be restarted using the
7714 // identity supplied by the user (foo, bar) to answer the challenge.
7715 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237716 MockWrite(
7717 "GET / HTTP/1.1\r\n"
7718 "Host: www.example.org\r\n"
7719 "Connection: keep-alive\r\n"
7720 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167721 };
7722
7723 MockRead data_reads3[] = {
7724 MockRead("HTTP/1.0 200 OK\r\n"),
7725 MockRead("Content-Length: 100\r\n\r\n"),
7726 MockRead(SYNCHRONOUS, OK),
7727 };
7728
7729 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7730 data_writes1, arraysize(data_writes1));
7731 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7732 data_writes2, arraysize(data_writes2));
7733 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7734 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077735 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7736 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7737 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167738
7739 TestCompletionCallback callback1;
7740
tfarina42834112016-09-22 13:38:207741 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167743
7744 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017745 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167746
bnc691fda62016-08-12 00:43:167747 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167748 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167749 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167751 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017752 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167753 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167754
bnc691fda62016-08-12 00:43:167755 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527756 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167757 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7758
7759 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167760 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167762 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017763 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167764 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167765
bnc691fda62016-08-12 00:43:167766 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527767 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167768
7769 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527770 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167771
7772 EXPECT_EQ(100, response->headers->GetContentLength());
7773
[email protected]ea9dc9a2009-09-05 00:43:327774 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557775 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327776}
7777
[email protected]2217aa22013-10-11 03:03:547778
7779// Test the request-challenge-retry sequence for basic auth when there is a
7780// correct identity in the URL, but its use is being suppressed. The identity
7781// from the URL should never be used.
bncd16676a2016-07-20 16:23:017782TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547783 HttpRequestInfo request;
7784 request.method = "GET";
bncce36dca22015-04-21 22:11:237785 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547786 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:107787 request.traffic_annotation =
7788 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547789
danakj1fd259a02016-04-16 03:17:097790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547792
7793 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237794 MockWrite(
7795 "GET / HTTP/1.1\r\n"
7796 "Host: www.example.org\r\n"
7797 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547798 };
7799
7800 MockRead data_reads1[] = {
7801 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7802 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7803 MockRead("Content-Length: 10\r\n\r\n"),
7804 MockRead(SYNCHRONOUS, ERR_FAILED),
7805 };
7806
7807 // After the challenge above, the transaction will be restarted using the
7808 // identity supplied by the user, not the one in the URL, to answer the
7809 // challenge.
7810 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237811 MockWrite(
7812 "GET / HTTP/1.1\r\n"
7813 "Host: www.example.org\r\n"
7814 "Connection: keep-alive\r\n"
7815 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547816 };
7817
7818 MockRead data_reads3[] = {
7819 MockRead("HTTP/1.0 200 OK\r\n"),
7820 MockRead("Content-Length: 100\r\n\r\n"),
7821 MockRead(SYNCHRONOUS, OK),
7822 };
7823
7824 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7825 data_writes1, arraysize(data_writes1));
7826 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7827 data_writes3, arraysize(data_writes3));
7828 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7829 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7830
7831 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207832 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547834 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017835 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167836 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547837
bnc691fda62016-08-12 00:43:167838 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527839 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547840 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7841
7842 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167843 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547845 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017846 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167847 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547848
bnc691fda62016-08-12 00:43:167849 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527850 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547851
7852 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527853 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547854 EXPECT_EQ(100, response->headers->GetContentLength());
7855
7856 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557857 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547858}
7859
[email protected]f9ee6b52008-11-08 06:46:237860// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017861TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097862 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237863
7864 // Transaction 1: authenticate (foo, bar) on MyRealm1
7865 {
[email protected]1c773ea12009-04-28 19:58:427866 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237867 request.method = "GET";
bncce36dca22015-04-21 22:11:237868 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:107869 request.traffic_annotation =
7870 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237871
bnc691fda62016-08-12 00:43:167872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277873
[email protected]f9ee6b52008-11-08 06:46:237874 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237875 MockWrite(
7876 "GET /x/y/z HTTP/1.1\r\n"
7877 "Host: www.example.org\r\n"
7878 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237879 };
7880
7881 MockRead data_reads1[] = {
7882 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7883 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7884 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067885 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237886 };
7887
7888 // Resend with authorization (username=foo, password=bar)
7889 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237890 MockWrite(
7891 "GET /x/y/z HTTP/1.1\r\n"
7892 "Host: www.example.org\r\n"
7893 "Connection: keep-alive\r\n"
7894 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237895 };
7896
7897 // Sever accepts the authorization.
7898 MockRead data_reads2[] = {
7899 MockRead("HTTP/1.0 200 OK\r\n"),
7900 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067901 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237902 };
7903
[email protected]31a2bfe2010-02-09 08:03:397904 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7905 data_writes1, arraysize(data_writes1));
7906 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7907 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077908 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7909 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237910
[email protected]49639fa2011-12-20 23:22:417911 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237912
tfarina42834112016-09-22 13:38:207913 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017914 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237915
7916 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017917 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237918
bnc691fda62016-08-12 00:43:167919 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527920 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047921 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237922
[email protected]49639fa2011-12-20 23:22:417923 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237924
bnc691fda62016-08-12 00:43:167925 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7926 callback2.callback());
robpercival214763f2016-07-01 23:27:017927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237928
7929 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017930 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237931
bnc691fda62016-08-12 00:43:167932 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527933 ASSERT_TRUE(response);
7934 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237935 EXPECT_EQ(100, response->headers->GetContentLength());
7936 }
7937
7938 // ------------------------------------------------------------------------
7939
7940 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7941 {
[email protected]1c773ea12009-04-28 19:58:427942 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237943 request.method = "GET";
7944 // Note that Transaction 1 was at /x/y/z, so this is in the same
7945 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237946 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:107947 request.traffic_annotation =
7948 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237949
bnc691fda62016-08-12 00:43:167950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277951
[email protected]f9ee6b52008-11-08 06:46:237952 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237953 MockWrite(
7954 "GET /x/y/a/b HTTP/1.1\r\n"
7955 "Host: www.example.org\r\n"
7956 "Connection: keep-alive\r\n"
7957 // Send preemptive authorization for MyRealm1
7958 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237959 };
7960
7961 // The server didn't like the preemptive authorization, and
7962 // challenges us for a different realm (MyRealm2).
7963 MockRead data_reads1[] = {
7964 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7965 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7966 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067967 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237968 };
7969
7970 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7971 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237972 MockWrite(
7973 "GET /x/y/a/b HTTP/1.1\r\n"
7974 "Host: www.example.org\r\n"
7975 "Connection: keep-alive\r\n"
7976 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237977 };
7978
7979 // Sever accepts the authorization.
7980 MockRead data_reads2[] = {
7981 MockRead("HTTP/1.0 200 OK\r\n"),
7982 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067983 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237984 };
7985
[email protected]31a2bfe2010-02-09 08:03:397986 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7987 data_writes1, arraysize(data_writes1));
7988 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7989 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077990 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7991 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237992
[email protected]49639fa2011-12-20 23:22:417993 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237994
tfarina42834112016-09-22 13:38:207995 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237997
7998 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017999 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238000
bnc691fda62016-08-12 00:43:168001 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528002 ASSERT_TRUE(response);
8003 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048004 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438005 EXPECT_EQ("http://www.example.org",
8006 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048007 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198008 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238009
[email protected]49639fa2011-12-20 23:22:418010 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238011
bnc691fda62016-08-12 00:43:168012 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8013 callback2.callback());
robpercival214763f2016-07-01 23:27:018014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238015
8016 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018017 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238018
bnc691fda62016-08-12 00:43:168019 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528020 ASSERT_TRUE(response);
8021 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238022 EXPECT_EQ(100, response->headers->GetContentLength());
8023 }
8024
8025 // ------------------------------------------------------------------------
8026
8027 // Transaction 3: Resend a request in MyRealm's protection space --
8028 // succeed with preemptive authorization.
8029 {
[email protected]1c773ea12009-04-28 19:58:428030 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238031 request.method = "GET";
bncce36dca22015-04-21 22:11:238032 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108033 request.traffic_annotation =
8034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238035
bnc691fda62016-08-12 00:43:168036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278037
[email protected]f9ee6b52008-11-08 06:46:238038 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238039 MockWrite(
8040 "GET /x/y/z2 HTTP/1.1\r\n"
8041 "Host: www.example.org\r\n"
8042 "Connection: keep-alive\r\n"
8043 // The authorization for MyRealm1 gets sent preemptively
8044 // (since the url is in the same protection space)
8045 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238046 };
8047
8048 // Sever accepts the preemptive authorization
8049 MockRead data_reads1[] = {
8050 MockRead("HTTP/1.0 200 OK\r\n"),
8051 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068052 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238053 };
8054
[email protected]31a2bfe2010-02-09 08:03:398055 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8056 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078057 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238058
[email protected]49639fa2011-12-20 23:22:418059 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238060
tfarina42834112016-09-22 13:38:208061 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238063
8064 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018065 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238066
bnc691fda62016-08-12 00:43:168067 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528068 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238069
wezca1070932016-05-26 20:30:528070 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238071 EXPECT_EQ(100, response->headers->GetContentLength());
8072 }
8073
8074 // ------------------------------------------------------------------------
8075
8076 // Transaction 4: request another URL in MyRealm (however the
8077 // url is not known to belong to the protection space, so no pre-auth).
8078 {
[email protected]1c773ea12009-04-28 19:58:428079 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238080 request.method = "GET";
bncce36dca22015-04-21 22:11:238081 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108082 request.traffic_annotation =
8083 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238084
bnc691fda62016-08-12 00:43:168085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278086
[email protected]f9ee6b52008-11-08 06:46:238087 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238088 MockWrite(
8089 "GET /x/1 HTTP/1.1\r\n"
8090 "Host: www.example.org\r\n"
8091 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238092 };
8093
8094 MockRead data_reads1[] = {
8095 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8096 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8097 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068098 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238099 };
8100
8101 // Resend with authorization from MyRealm's cache.
8102 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238103 MockWrite(
8104 "GET /x/1 HTTP/1.1\r\n"
8105 "Host: www.example.org\r\n"
8106 "Connection: keep-alive\r\n"
8107 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238108 };
8109
8110 // Sever accepts the authorization.
8111 MockRead data_reads2[] = {
8112 MockRead("HTTP/1.0 200 OK\r\n"),
8113 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068114 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238115 };
8116
[email protected]31a2bfe2010-02-09 08:03:398117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8118 data_writes1, arraysize(data_writes1));
8119 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8120 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078121 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8122 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238123
[email protected]49639fa2011-12-20 23:22:418124 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238125
tfarina42834112016-09-22 13:38:208126 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238128
8129 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018130 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238131
bnc691fda62016-08-12 00:43:168132 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418133 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168134 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018135 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228136 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018137 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168138 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228139
bnc691fda62016-08-12 00:43:168140 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528141 ASSERT_TRUE(response);
8142 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238143 EXPECT_EQ(100, response->headers->GetContentLength());
8144 }
8145
8146 // ------------------------------------------------------------------------
8147
8148 // Transaction 5: request a URL in MyRealm, but the server rejects the
8149 // cached identity. Should invalidate and re-prompt.
8150 {
[email protected]1c773ea12009-04-28 19:58:428151 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238152 request.method = "GET";
bncce36dca22015-04-21 22:11:238153 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:108154 request.traffic_annotation =
8155 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238156
bnc691fda62016-08-12 00:43:168157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278158
[email protected]f9ee6b52008-11-08 06:46:238159 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238160 MockWrite(
8161 "GET /p/q/t HTTP/1.1\r\n"
8162 "Host: www.example.org\r\n"
8163 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238164 };
8165
8166 MockRead data_reads1[] = {
8167 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8168 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8169 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068170 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238171 };
8172
8173 // Resend with authorization from cache for MyRealm.
8174 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238175 MockWrite(
8176 "GET /p/q/t HTTP/1.1\r\n"
8177 "Host: www.example.org\r\n"
8178 "Connection: keep-alive\r\n"
8179 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238180 };
8181
8182 // Sever rejects the authorization.
8183 MockRead data_reads2[] = {
8184 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8185 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8186 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068187 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238188 };
8189
8190 // At this point we should prompt for new credentials for MyRealm.
8191 // Restart with username=foo3, password=foo4.
8192 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238193 MockWrite(
8194 "GET /p/q/t HTTP/1.1\r\n"
8195 "Host: www.example.org\r\n"
8196 "Connection: keep-alive\r\n"
8197 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238198 };
8199
8200 // Sever accepts the authorization.
8201 MockRead data_reads3[] = {
8202 MockRead("HTTP/1.0 200 OK\r\n"),
8203 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068204 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238205 };
8206
[email protected]31a2bfe2010-02-09 08:03:398207 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8208 data_writes1, arraysize(data_writes1));
8209 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8210 data_writes2, arraysize(data_writes2));
8211 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8212 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078213 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8214 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8215 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238216
[email protected]49639fa2011-12-20 23:22:418217 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238218
tfarina42834112016-09-22 13:38:208219 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238221
8222 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018223 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238224
bnc691fda62016-08-12 00:43:168225 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418226 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168227 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228229 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018230 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168231 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228232
bnc691fda62016-08-12 00:43:168233 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528234 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048235 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238236
[email protected]49639fa2011-12-20 23:22:418237 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238238
bnc691fda62016-08-12 00:43:168239 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8240 callback3.callback());
robpercival214763f2016-07-01 23:27:018241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238242
[email protected]0757e7702009-03-27 04:00:228243 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018244 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238245
bnc691fda62016-08-12 00:43:168246 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528247 ASSERT_TRUE(response);
8248 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238249 EXPECT_EQ(100, response->headers->GetContentLength());
8250 }
8251}
[email protected]89ceba9a2009-03-21 03:46:068252
[email protected]3c32c5f2010-05-18 15:18:128253// Tests that nonce count increments when multiple auth attempts
8254// are started with the same nonce.
bncd16676a2016-07-20 16:23:018255TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448256 HttpAuthHandlerDigest::Factory* digest_factory =
8257 new HttpAuthHandlerDigest::Factory();
8258 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8259 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8260 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078261 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128263
8264 // Transaction 1: authenticate (foo, bar) on MyRealm1
8265 {
[email protected]3c32c5f2010-05-18 15:18:128266 HttpRequestInfo request;
8267 request.method = "GET";
bncce36dca22015-04-21 22:11:238268 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108269 request.traffic_annotation =
8270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128271
bnc691fda62016-08-12 00:43:168272 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278273
[email protected]3c32c5f2010-05-18 15:18:128274 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238275 MockWrite(
8276 "GET /x/y/z HTTP/1.1\r\n"
8277 "Host: www.example.org\r\n"
8278 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128279 };
8280
8281 MockRead data_reads1[] = {
8282 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8283 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8284 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068285 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128286 };
8287
8288 // Resend with authorization (username=foo, password=bar)
8289 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238290 MockWrite(
8291 "GET /x/y/z HTTP/1.1\r\n"
8292 "Host: www.example.org\r\n"
8293 "Connection: keep-alive\r\n"
8294 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8295 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8296 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8297 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128298 };
8299
8300 // Sever accepts the authorization.
8301 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088302 MockRead("HTTP/1.0 200 OK\r\n"),
8303 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128304 };
8305
8306 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8307 data_writes1, arraysize(data_writes1));
8308 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8309 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128312
[email protected]49639fa2011-12-20 23:22:418313 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128314
tfarina42834112016-09-22 13:38:208315 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018316 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128317
8318 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018319 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128320
bnc691fda62016-08-12 00:43:168321 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528322 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048323 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128324
[email protected]49639fa2011-12-20 23:22:418325 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128326
bnc691fda62016-08-12 00:43:168327 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8328 callback2.callback());
robpercival214763f2016-07-01 23:27:018329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128330
8331 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018332 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128333
bnc691fda62016-08-12 00:43:168334 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528335 ASSERT_TRUE(response);
8336 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128337 }
8338
8339 // ------------------------------------------------------------------------
8340
8341 // Transaction 2: Request another resource in digestive's protection space.
8342 // This will preemptively add an Authorization header which should have an
8343 // "nc" value of 2 (as compared to 1 in the first use.
8344 {
[email protected]3c32c5f2010-05-18 15:18:128345 HttpRequestInfo request;
8346 request.method = "GET";
8347 // Note that Transaction 1 was at /x/y/z, so this is in the same
8348 // protection space as digest.
bncce36dca22015-04-21 22:11:238349 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108350 request.traffic_annotation =
8351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128352
bnc691fda62016-08-12 00:43:168353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278354
[email protected]3c32c5f2010-05-18 15:18:128355 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238356 MockWrite(
8357 "GET /x/y/a/b HTTP/1.1\r\n"
8358 "Host: www.example.org\r\n"
8359 "Connection: keep-alive\r\n"
8360 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8361 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8362 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8363 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128364 };
8365
8366 // Sever accepts the authorization.
8367 MockRead data_reads1[] = {
8368 MockRead("HTTP/1.0 200 OK\r\n"),
8369 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068370 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128371 };
8372
8373 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8374 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078375 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128376
[email protected]49639fa2011-12-20 23:22:418377 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128378
tfarina42834112016-09-22 13:38:208379 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128381
8382 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018383 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128384
bnc691fda62016-08-12 00:43:168385 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528386 ASSERT_TRUE(response);
8387 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128388 }
8389}
8390
[email protected]89ceba9a2009-03-21 03:46:068391// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018392TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068393 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068396
8397 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168398 trans.read_buf_ = new IOBuffer(15);
8399 trans.read_buf_len_ = 15;
8400 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068401
8402 // Setup state in response_
bnc691fda62016-08-12 00:43:168403 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578404 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088405 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578406 response->response_time = base::Time::Now();
8407 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068408
8409 { // Setup state for response_.vary_data
8410 HttpRequestInfo request;
8411 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8412 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278413 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438414 request.extra_headers.SetHeader("Foo", "1");
8415 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508416 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068417 }
8418
8419 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168420 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068421
8422 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168423 EXPECT_FALSE(trans.read_buf_);
8424 EXPECT_EQ(0, trans.read_buf_len_);
8425 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528426 EXPECT_FALSE(response->auth_challenge);
8427 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048428 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088429 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578430 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068431}
8432
[email protected]bacff652009-03-31 17:50:338433// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018434TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338435 HttpRequestInfo request;
8436 request.method = "GET";
bncce36dca22015-04-21 22:11:238437 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108438 request.traffic_annotation =
8439 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338440
danakj1fd259a02016-04-16 03:17:098441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278443
[email protected]bacff652009-03-31 17:50:338444 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238445 MockWrite(
8446 "GET / HTTP/1.1\r\n"
8447 "Host: www.example.org\r\n"
8448 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338449 };
8450
8451 MockRead data_reads[] = {
8452 MockRead("HTTP/1.0 200 OK\r\n"),
8453 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8454 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068455 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338456 };
8457
[email protected]5ecc992a42009-11-11 01:41:598458 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398459 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8460 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068461 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8462 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338463
[email protected]bb88e1d32013-05-03 23:11:078464 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8465 session_deps_.socket_factory->AddSocketDataProvider(&data);
8466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338468
[email protected]49639fa2011-12-20 23:22:418469 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338470
tfarina42834112016-09-22 13:38:208471 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338473
8474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018475 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338476
bnc691fda62016-08-12 00:43:168477 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338479
8480 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018481 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338482
bnc691fda62016-08-12 00:43:168483 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338484
wezca1070932016-05-26 20:30:528485 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338486 EXPECT_EQ(100, response->headers->GetContentLength());
8487}
8488
8489// Test HTTPS connections to a site with a bad certificate, going through a
8490// proxy
bncd16676a2016-07-20 16:23:018491TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598492 session_deps_.proxy_resolution_service =
8493 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:338494
8495 HttpRequestInfo request;
8496 request.method = "GET";
bncce36dca22015-04-21 22:11:238497 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108498 request.traffic_annotation =
8499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338500
8501 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178502 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8503 "Host: www.example.org:443\r\n"
8504 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338505 };
8506
8507 MockRead proxy_reads[] = {
8508 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068509 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338510 };
8511
8512 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178513 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8514 "Host: www.example.org:443\r\n"
8515 "Proxy-Connection: keep-alive\r\n\r\n"),
8516 MockWrite("GET / HTTP/1.1\r\n"
8517 "Host: www.example.org\r\n"
8518 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338519 };
8520
8521 MockRead data_reads[] = {
8522 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8523 MockRead("HTTP/1.0 200 OK\r\n"),
8524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8525 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068526 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338527 };
8528
[email protected]31a2bfe2010-02-09 08:03:398529 StaticSocketDataProvider ssl_bad_certificate(
8530 proxy_reads, arraysize(proxy_reads),
8531 proxy_writes, arraysize(proxy_writes));
8532 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8533 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068534 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8535 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338536
[email protected]bb88e1d32013-05-03 23:11:078537 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8538 session_deps_.socket_factory->AddSocketDataProvider(&data);
8539 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8540 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338541
[email protected]49639fa2011-12-20 23:22:418542 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338543
8544 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078545 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338546
danakj1fd259a02016-04-16 03:17:098547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338549
tfarina42834112016-09-22 13:38:208550 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018551 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338552
8553 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018554 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338555
bnc691fda62016-08-12 00:43:168556 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338558
8559 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018560 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338561
bnc691fda62016-08-12 00:43:168562 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338563
wezca1070932016-05-26 20:30:528564 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338565 EXPECT_EQ(100, response->headers->GetContentLength());
8566 }
8567}
8568
[email protected]2df19bb2010-08-25 20:13:468569
8570// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018571TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598572 session_deps_.proxy_resolution_service =
8573 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518574 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078575 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468576
8577 HttpRequestInfo request;
8578 request.method = "GET";
bncce36dca22015-04-21 22:11:238579 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108580 request.traffic_annotation =
8581 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468582
8583 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178584 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8585 "Host: www.example.org:443\r\n"
8586 "Proxy-Connection: keep-alive\r\n\r\n"),
8587 MockWrite("GET / HTTP/1.1\r\n"
8588 "Host: www.example.org\r\n"
8589 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468590 };
8591
8592 MockRead data_reads[] = {
8593 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8594 MockRead("HTTP/1.1 200 OK\r\n"),
8595 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8596 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068597 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468598 };
8599
8600 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8601 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068602 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8603 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468604
[email protected]bb88e1d32013-05-03 23:11:078605 session_deps_.socket_factory->AddSocketDataProvider(&data);
8606 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8607 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468608
[email protected]49639fa2011-12-20 23:22:418609 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468610
danakj1fd259a02016-04-16 03:17:098611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468613
tfarina42834112016-09-22 13:38:208614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468616
8617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018618 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168619 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468620
wezca1070932016-05-26 20:30:528621 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468622
tbansal2ecbbc72016-10-06 17:15:478623 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468624 EXPECT_TRUE(response->headers->IsKeepAlive());
8625 EXPECT_EQ(200, response->headers->response_code());
8626 EXPECT_EQ(100, response->headers->GetContentLength());
8627 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208628
8629 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168630 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208631 TestLoadTimingNotReusedWithPac(load_timing_info,
8632 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468633}
8634
[email protected]511f6f52010-12-17 03:58:298635// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018636TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598637 session_deps_.proxy_resolution_service =
8638 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518639 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078640 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298641
8642 HttpRequestInfo request;
8643 request.method = "GET";
bncce36dca22015-04-21 22:11:238644 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108645 request.traffic_annotation =
8646 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298647
8648 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178649 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8650 "Host: www.example.org:443\r\n"
8651 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298652 };
8653
8654 MockRead data_reads[] = {
8655 MockRead("HTTP/1.1 302 Redirect\r\n"),
8656 MockRead("Location: http://login.example.com/\r\n"),
8657 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068658 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298659 };
8660
8661 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8662 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068663 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298664
[email protected]bb88e1d32013-05-03 23:11:078665 session_deps_.socket_factory->AddSocketDataProvider(&data);
8666 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298667
[email protected]49639fa2011-12-20 23:22:418668 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298669
danakj1fd259a02016-04-16 03:17:098670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298672
tfarina42834112016-09-22 13:38:208673 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298675
8676 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018677 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168678 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298679
wezca1070932016-05-26 20:30:528680 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298681
8682 EXPECT_EQ(302, response->headers->response_code());
8683 std::string url;
8684 EXPECT_TRUE(response->headers->IsRedirect(&url));
8685 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208686
8687 // In the case of redirects from proxies, HttpNetworkTransaction returns
8688 // timing for the proxy connection instead of the connection to the host,
8689 // and no send / receive times.
8690 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8691 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168692 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208693
8694 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198695 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208696
8697 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8698 EXPECT_LE(load_timing_info.proxy_resolve_start,
8699 load_timing_info.proxy_resolve_end);
8700 EXPECT_LE(load_timing_info.proxy_resolve_end,
8701 load_timing_info.connect_timing.connect_start);
8702 ExpectConnectTimingHasTimes(
8703 load_timing_info.connect_timing,
8704 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8705
8706 EXPECT_TRUE(load_timing_info.send_start.is_null());
8707 EXPECT_TRUE(load_timing_info.send_end.is_null());
8708 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298709}
8710
8711// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018712TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598713 session_deps_.proxy_resolution_service =
8714 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298715
8716 HttpRequestInfo request;
8717 request.method = "GET";
bncce36dca22015-04-21 22:11:238718 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108719 request.traffic_annotation =
8720 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298721
bncdf80d44fd2016-07-15 20:27:418722 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238723 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418724 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088725 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298726 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418727 CreateMockWrite(conn, 0, SYNCHRONOUS),
8728 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298729 };
8730
8731 static const char* const kExtraHeaders[] = {
8732 "location",
8733 "http://login.example.com/",
8734 };
bnc42331402016-07-25 13:36:158735 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238736 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298737 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418738 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298739 };
8740
rch8e6c6c42015-05-01 14:05:138741 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8742 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068743 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368744 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298745
[email protected]bb88e1d32013-05-03 23:11:078746 session_deps_.socket_factory->AddSocketDataProvider(&data);
8747 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298748
[email protected]49639fa2011-12-20 23:22:418749 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298750
danakj1fd259a02016-04-16 03:17:098751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298753
tfarina42834112016-09-22 13:38:208754 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298756
8757 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018758 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168759 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298760
wezca1070932016-05-26 20:30:528761 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298762
8763 EXPECT_EQ(302, response->headers->response_code());
8764 std::string url;
8765 EXPECT_TRUE(response->headers->IsRedirect(&url));
8766 EXPECT_EQ("http://login.example.com/", url);
8767}
8768
[email protected]4eddbc732012-08-09 05:40:178769// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018770TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598771 session_deps_.proxy_resolution_service =
8772 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298773
8774 HttpRequestInfo request;
8775 request.method = "GET";
bncce36dca22015-04-21 22:11:238776 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108777 request.traffic_annotation =
8778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298779
8780 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178781 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8782 "Host: www.example.org:443\r\n"
8783 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298784 };
8785
8786 MockRead data_reads[] = {
8787 MockRead("HTTP/1.1 404 Not Found\r\n"),
8788 MockRead("Content-Length: 23\r\n\r\n"),
8789 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068790 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298791 };
8792
8793 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8794 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068795 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298796
[email protected]bb88e1d32013-05-03 23:11:078797 session_deps_.socket_factory->AddSocketDataProvider(&data);
8798 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298799
[email protected]49639fa2011-12-20 23:22:418800 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298801
danakj1fd259a02016-04-16 03:17:098802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168803 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298804
tfarina42834112016-09-22 13:38:208805 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298807
8808 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018809 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298810
ttuttle960fcbf2016-04-19 13:26:328811 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298812}
8813
[email protected]4eddbc732012-08-09 05:40:178814// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018815TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598816 session_deps_.proxy_resolution_service =
8817 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298818
8819 HttpRequestInfo request;
8820 request.method = "GET";
bncce36dca22015-04-21 22:11:238821 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108822 request.traffic_annotation =
8823 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298824
bncdf80d44fd2016-07-15 20:27:418825 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238826 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418827 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088828 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298829 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418830 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298831 };
8832
8833 static const char* const kExtraHeaders[] = {
8834 "location",
8835 "http://login.example.com/",
8836 };
bnc42331402016-07-25 13:36:158837 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238838 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Bence Békyd74f4382018-02-20 18:26:198839 SpdySerializedFrame body(
8840 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298841 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418842 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138843 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298844 };
8845
rch8e6c6c42015-05-01 14:05:138846 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8847 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068848 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368849 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298850
[email protected]bb88e1d32013-05-03 23:11:078851 session_deps_.socket_factory->AddSocketDataProvider(&data);
8852 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298853
[email protected]49639fa2011-12-20 23:22:418854 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298855
danakj1fd259a02016-04-16 03:17:098856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168857 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298858
tfarina42834112016-09-22 13:38:208859 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298861
8862 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018863 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298864
ttuttle960fcbf2016-04-19 13:26:328865 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298866}
8867
[email protected]0c5fb722012-02-28 11:50:358868// Test the request-challenge-retry sequence for basic auth, through
8869// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018870TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358871 HttpRequestInfo request;
8872 request.method = "GET";
bncce36dca22015-04-21 22:11:238873 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358874 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298875 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:108876 request.traffic_annotation =
8877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358878
8879 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598880 session_deps_.proxy_resolution_service =
8881 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518882 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078883 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358885
8886 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418887 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238888 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418889 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088890 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388891 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358892
bnc691fda62016-08-12 00:43:168893 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358894 // be issuing -- the final header line contains the credentials.
8895 const char* const kAuthCredentials[] = {
8896 "proxy-authorization", "Basic Zm9vOmJhcg==",
8897 };
bncdf80d44fd2016-07-15 20:27:418898 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348899 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238900 HostPortPair("www.example.org", 443)));
8901 // fetch https://www.example.org/ via HTTP
8902 const char get[] =
8903 "GET / HTTP/1.1\r\n"
8904 "Host: www.example.org\r\n"
8905 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418906 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198907 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358908
8909 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418910 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8911 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358912 };
8913
8914 // The proxy responds to the connect with a 407, using a persistent
8915 // connection.
thestig9d3bb0c2015-01-24 00:49:518916 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358917 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358918 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8919 };
bnc42331402016-07-25 13:36:158920 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418921 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358922
bnc42331402016-07-25 13:36:158923 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358924 const char resp[] = "HTTP/1.1 200 OK\r\n"
8925 "Content-Length: 5\r\n\r\n";
8926
bncdf80d44fd2016-07-15 20:27:418927 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198928 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
bncdf80d44fd2016-07-15 20:27:418929 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198930 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358931 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418932 CreateMockRead(conn_auth_resp, 1, ASYNC),
8933 CreateMockRead(conn_resp, 4, ASYNC),
8934 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8935 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138936 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358937 };
8938
rch8e6c6c42015-05-01 14:05:138939 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8940 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078941 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358942 // Negotiate SPDY to the proxy
8943 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368944 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078945 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358946 // Vanilla SSL to the server
8947 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078948 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358949
8950 TestCompletionCallback callback1;
8951
bnc87dcefc2017-05-25 12:47:588952 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198953 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358954
8955 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358957
8958 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018959 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468960 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358961 log.GetEntries(&entries);
8962 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008963 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8964 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358965 ExpectLogContainsSomewhere(
8966 entries, pos,
mikecirone8b85c432016-09-08 19:11:008967 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8968 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358969
8970 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528971 ASSERT_TRUE(response);
8972 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358973 EXPECT_EQ(407, response->headers->response_code());
8974 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528975 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438976 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358977
8978 TestCompletionCallback callback2;
8979
8980 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8981 callback2.callback());
robpercival214763f2016-07-01 23:27:018982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358983
8984 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018985 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358986
8987 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528988 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358989
8990 EXPECT_TRUE(response->headers->IsKeepAlive());
8991 EXPECT_EQ(200, response->headers->response_code());
8992 EXPECT_EQ(5, response->headers->GetContentLength());
8993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8994
8995 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528996 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358997
[email protected]029c83b62013-01-24 05:28:208998 LoadTimingInfo load_timing_info;
8999 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9000 TestLoadTimingNotReusedWithPac(load_timing_info,
9001 CONNECT_TIMING_HAS_SSL_TIMES);
9002
[email protected]0c5fb722012-02-28 11:50:359003 trans.reset();
9004 session->CloseAllConnections();
9005}
9006
[email protected]7c6f7ba2012-04-03 04:09:299007// Test that an explicitly trusted SPDY proxy can push a resource from an
9008// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019009TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159010 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199011 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159012 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9013 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299014 HttpRequestInfo request;
9015 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109016 request.traffic_annotation =
9017 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299018
[email protected]7c6f7ba2012-04-03 04:09:299019 request.method = "GET";
bncce36dca22015-04-21 22:11:239020 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299021 push_request.method = "GET";
9022 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109023 push_request.traffic_annotation =
9024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299025
tbansal28e68f82016-02-04 02:56:159026 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599027 session_deps_.proxy_resolution_service =
9028 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:519029 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079030 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509031
inlinechan894515af2016-12-09 02:40:109032 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509033
danakj1fd259a02016-04-16 03:17:099034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299035
bncdf80d44fd2016-07-15 20:27:419036 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459037 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359038 SpdySerializedFrame stream2_priority(
9039 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299040
9041 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419042 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359043 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299044 };
9045
Bence Béky7bf94362018-01-10 13:19:369046 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9047 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9048
bncdf80d44fd2016-07-15 20:27:419049 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159050 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299051
bncdf80d44fd2016-07-15 20:27:419052 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299053
Bence Békyd74f4382018-02-20 18:26:199054 SpdySerializedFrame stream2_body(
9055 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299056
9057 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369058 CreateMockRead(stream2_syn, 1, ASYNC),
9059 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359060 CreateMockRead(stream1_body, 4, ASYNC),
9061 CreateMockRead(stream2_body, 5, ASYNC),
9062 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299063 };
9064
rch8e6c6c42015-05-01 14:05:139065 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9066 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079067 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299068 // Negotiate SPDY to the proxy
9069 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369070 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079071 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299072
bnc87dcefc2017-05-25 12:47:589073 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199074 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299075 TestCompletionCallback callback;
9076 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299078
9079 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019080 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299081 const HttpResponseInfo* response = trans->GetResponseInfo();
9082
bnc87dcefc2017-05-25 12:47:589083 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199084 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509085 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299087
9088 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019089 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299090 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9091
wezca1070932016-05-26 20:30:529092 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299093 EXPECT_TRUE(response->headers->IsKeepAlive());
9094
9095 EXPECT_EQ(200, response->headers->response_code());
9096 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9097
9098 std::string response_data;
9099 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019100 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299101 EXPECT_EQ("hello!", response_data);
9102
[email protected]029c83b62013-01-24 05:28:209103 LoadTimingInfo load_timing_info;
9104 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9105 TestLoadTimingNotReusedWithPac(load_timing_info,
9106 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9107
[email protected]7c6f7ba2012-04-03 04:09:299108 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529109 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299110 EXPECT_EQ(200, push_response->headers->response_code());
9111
9112 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299114 EXPECT_EQ("pushed", response_data);
9115
[email protected]029c83b62013-01-24 05:28:209116 LoadTimingInfo push_load_timing_info;
9117 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9118 TestLoadTimingReusedWithPac(push_load_timing_info);
9119 // The transactions should share a socket ID, despite being for different
9120 // origins.
9121 EXPECT_EQ(load_timing_info.socket_log_id,
9122 push_load_timing_info.socket_log_id);
9123
[email protected]7c6f7ba2012-04-03 04:09:299124 trans.reset();
9125 push_trans.reset();
9126 session->CloseAllConnections();
9127}
9128
[email protected]8c843192012-04-05 07:15:009129// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019130TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159131 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199132 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159133 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9134 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009135 HttpRequestInfo request;
9136
9137 request.method = "GET";
bncce36dca22015-04-21 22:11:239138 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109139 request.traffic_annotation =
9140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009141
Lily Houghton8c2f97d2018-01-22 05:06:599142 session_deps_.proxy_resolution_service =
9143 ProxyResolutionService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:519144 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079145 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509146
9147 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109148 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509149
danakj1fd259a02016-04-16 03:17:099150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009151
bncdf80d44fd2016-07-15 20:27:419152 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459153 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009154
bncdf80d44fd2016-07-15 20:27:419155 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089156 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009157
9158 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419159 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009160 };
9161
bncdf80d44fd2016-07-15 20:27:419162 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159163 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009164
bncdf80d44fd2016-07-15 20:27:419165 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009166
bncdf80d44fd2016-07-15 20:27:419167 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559168 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009169
9170 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419171 CreateMockRead(stream1_reply, 1, ASYNC),
9172 CreateMockRead(stream2_syn, 2, ASYNC),
9173 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599174 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009175 };
9176
rch8e6c6c42015-05-01 14:05:139177 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9178 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079179 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009180 // Negotiate SPDY to the proxy
9181 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369182 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079183 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009184
bnc87dcefc2017-05-25 12:47:589185 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199186 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009187 TestCompletionCallback callback;
9188 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009190
9191 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019192 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009193 const HttpResponseInfo* response = trans->GetResponseInfo();
9194
wezca1070932016-05-26 20:30:529195 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009196 EXPECT_TRUE(response->headers->IsKeepAlive());
9197
9198 EXPECT_EQ(200, response->headers->response_code());
9199 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9200
9201 std::string response_data;
9202 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019203 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009204 EXPECT_EQ("hello!", response_data);
9205
9206 trans.reset();
9207 session->CloseAllConnections();
9208}
9209
tbansal8ef1d3e2016-02-03 04:05:429210// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9211// resources.
bncd16676a2016-07-20 16:23:019212TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159213 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199214 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159215 proxy_delegate->set_trusted_spdy_proxy(
9216 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9217
tbansal8ef1d3e2016-02-03 04:05:429218 HttpRequestInfo request;
9219
9220 request.method = "GET";
9221 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109222 request.traffic_annotation =
9223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429224
9225 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599226 session_deps_.proxy_resolution_service =
9227 ProxyResolutionService::CreateFixed("https://myproxy:70");
tbansal8ef1d3e2016-02-03 04:05:429228 BoundTestNetLog log;
9229 session_deps_.net_log = log.bound().net_log();
9230
9231 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109232 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429233
danakj1fd259a02016-04-16 03:17:099234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429235
bncdf80d44fd2016-07-15 20:27:419236 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459237 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359238 SpdySerializedFrame stream2_priority(
9239 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429240
9241 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419242 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359243 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429244 };
9245
bncdf80d44fd2016-07-15 20:27:419246 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159247 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429248
bncdf80d44fd2016-07-15 20:27:419249 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339250 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499251
bncdf80d44fd2016-07-15 20:27:419252 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429253
bncdf80d44fd2016-07-15 20:27:419254 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159255 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429256
bncdf80d44fd2016-07-15 20:27:419257 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429258
9259 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419260 CreateMockRead(stream1_reply, 1, ASYNC),
9261 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359262 CreateMockRead(stream1_body, 4, ASYNC),
9263 CreateMockRead(stream2_body, 5, ASYNC),
9264 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429265 };
9266
9267 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9268 arraysize(spdy_writes));
9269 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9270 // Negotiate SPDY to the proxy
9271 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369272 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429273 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9274
bnc87dcefc2017-05-25 12:47:589275 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199276 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429277 TestCompletionCallback callback;
9278 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019279 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429280
9281 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019282 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429283 const HttpResponseInfo* response = trans->GetResponseInfo();
9284
wezca1070932016-05-26 20:30:529285 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429286 EXPECT_TRUE(response->headers->IsKeepAlive());
9287
9288 EXPECT_EQ(200, response->headers->response_code());
9289 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9290
9291 std::string response_data;
9292 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019293 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429294 EXPECT_EQ("hello!", response_data);
9295
9296 trans.reset();
9297 session->CloseAllConnections();
9298}
9299
[email protected]2df19bb2010-08-25 20:13:469300// Test HTTPS connections to a site with a bad certificate, going through an
9301// HTTPS proxy
bncd16676a2016-07-20 16:23:019302TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599303 session_deps_.proxy_resolution_service =
9304 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:469305
9306 HttpRequestInfo request;
9307 request.method = "GET";
bncce36dca22015-04-21 22:11:239308 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109309 request.traffic_annotation =
9310 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469311
9312 // Attempt to fetch the URL from a server with a bad cert
9313 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179314 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9315 "Host: www.example.org:443\r\n"
9316 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469317 };
9318
9319 MockRead bad_cert_reads[] = {
9320 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069321 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469322 };
9323
9324 // Attempt to fetch the URL with a good cert
9325 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179326 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9327 "Host: www.example.org:443\r\n"
9328 "Proxy-Connection: keep-alive\r\n\r\n"),
9329 MockWrite("GET / HTTP/1.1\r\n"
9330 "Host: www.example.org\r\n"
9331 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469332 };
9333
9334 MockRead good_cert_reads[] = {
9335 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9336 MockRead("HTTP/1.0 200 OK\r\n"),
9337 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9338 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069339 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469340 };
9341
9342 StaticSocketDataProvider ssl_bad_certificate(
9343 bad_cert_reads, arraysize(bad_cert_reads),
9344 bad_cert_writes, arraysize(bad_cert_writes));
9345 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9346 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069347 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9348 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469349
9350 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9352 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469354
9355 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9357 session_deps_.socket_factory->AddSocketDataProvider(&data);
9358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469359
[email protected]49639fa2011-12-20 23:22:419360 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469361
danakj1fd259a02016-04-16 03:17:099362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469364
tfarina42834112016-09-22 13:38:209365 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469367
9368 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019369 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469370
bnc691fda62016-08-12 00:43:169371 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469373
9374 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019375 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469376
bnc691fda62016-08-12 00:43:169377 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469378
wezca1070932016-05-26 20:30:529379 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469380 EXPECT_EQ(100, response->headers->GetContentLength());
9381}
9382
bncd16676a2016-07-20 16:23:019383TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429384 HttpRequestInfo request;
9385 request.method = "GET";
bncce36dca22015-04-21 22:11:239386 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439387 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9388 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109389 request.traffic_annotation =
9390 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429391
danakj1fd259a02016-04-16 03:17:099392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279394
[email protected]1c773ea12009-04-28 19:58:429395 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239396 MockWrite(
9397 "GET / HTTP/1.1\r\n"
9398 "Host: www.example.org\r\n"
9399 "Connection: keep-alive\r\n"
9400 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429401 };
9402
9403 // Lastly, the server responds with the actual content.
9404 MockRead data_reads[] = {
9405 MockRead("HTTP/1.0 200 OK\r\n"),
9406 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9407 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069408 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429409 };
9410
[email protected]31a2bfe2010-02-09 08:03:399411 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9412 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079413 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429414
[email protected]49639fa2011-12-20 23:22:419415 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429416
tfarina42834112016-09-22 13:38:209417 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429419
9420 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019421 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429422}
9423
bncd16676a2016-07-20 16:23:019424TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299425 HttpRequestInfo request;
9426 request.method = "GET";
bncce36dca22015-04-21 22:11:239427 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299428 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9429 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109430 request.traffic_annotation =
9431 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299432
Lily Houghton8c2f97d2018-01-22 05:06:599433 session_deps_.proxy_resolution_service =
9434 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:099435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279437
[email protected]da81f132010-08-18 23:39:299438 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179439 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9440 "Host: www.example.org:443\r\n"
9441 "Proxy-Connection: keep-alive\r\n"
9442 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299443 };
9444 MockRead data_reads[] = {
9445 // Return an error, so the transaction stops here (this test isn't
9446 // interested in the rest).
9447 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9448 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9449 MockRead("Proxy-Connection: close\r\n\r\n"),
9450 };
9451
9452 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9453 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079454 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299455
[email protected]49639fa2011-12-20 23:22:419456 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299457
tfarina42834112016-09-22 13:38:209458 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299460
9461 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019462 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299463}
9464
bncd16676a2016-07-20 16:23:019465TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429466 HttpRequestInfo request;
9467 request.method = "GET";
bncce36dca22015-04-21 22:11:239468 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169469 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9470 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:109471 request.traffic_annotation =
9472 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429473
danakj1fd259a02016-04-16 03:17:099474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279476
[email protected]1c773ea12009-04-28 19:58:429477 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239478 MockWrite(
9479 "GET / HTTP/1.1\r\n"
9480 "Host: www.example.org\r\n"
9481 "Connection: keep-alive\r\n"
9482 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429483 };
9484
9485 // Lastly, the server responds with the actual content.
9486 MockRead data_reads[] = {
9487 MockRead("HTTP/1.0 200 OK\r\n"),
9488 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9489 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069490 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429491 };
9492
[email protected]31a2bfe2010-02-09 08:03:399493 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9494 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079495 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429496
[email protected]49639fa2011-12-20 23:22:419497 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429498
tfarina42834112016-09-22 13:38:209499 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429501
9502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019503 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429504}
9505
bncd16676a2016-07-20 16:23:019506TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429507 HttpRequestInfo request;
9508 request.method = "POST";
bncce36dca22015-04-21 22:11:239509 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109510 request.traffic_annotation =
9511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429512
danakj1fd259a02016-04-16 03:17:099513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279515
[email protected]1c773ea12009-04-28 19:58:429516 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239517 MockWrite(
9518 "POST / HTTP/1.1\r\n"
9519 "Host: www.example.org\r\n"
9520 "Connection: keep-alive\r\n"
9521 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429522 };
9523
9524 // Lastly, the server responds with the actual content.
9525 MockRead data_reads[] = {
9526 MockRead("HTTP/1.0 200 OK\r\n"),
9527 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9528 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069529 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429530 };
9531
[email protected]31a2bfe2010-02-09 08:03:399532 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9533 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079534 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429535
[email protected]49639fa2011-12-20 23:22:419536 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429537
tfarina42834112016-09-22 13:38:209538 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429540
9541 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019542 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429543}
9544
bncd16676a2016-07-20 16:23:019545TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429546 HttpRequestInfo request;
9547 request.method = "PUT";
bncce36dca22015-04-21 22:11:239548 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109549 request.traffic_annotation =
9550 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429551
danakj1fd259a02016-04-16 03:17:099552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279554
[email protected]1c773ea12009-04-28 19:58:429555 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239556 MockWrite(
9557 "PUT / HTTP/1.1\r\n"
9558 "Host: www.example.org\r\n"
9559 "Connection: keep-alive\r\n"
9560 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429561 };
9562
9563 // Lastly, the server responds with the actual content.
9564 MockRead data_reads[] = {
9565 MockRead("HTTP/1.0 200 OK\r\n"),
9566 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9567 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069568 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429569 };
9570
[email protected]31a2bfe2010-02-09 08:03:399571 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9572 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079573 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429574
[email protected]49639fa2011-12-20 23:22:419575 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429576
tfarina42834112016-09-22 13:38:209577 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019578 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429579
9580 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019581 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429582}
9583
bncd16676a2016-07-20 16:23:019584TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429585 HttpRequestInfo request;
9586 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239587 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109588 request.traffic_annotation =
9589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429590
danakj1fd259a02016-04-16 03:17:099591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279593
[email protected]1c773ea12009-04-28 19:58:429594 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139595 MockWrite("HEAD / HTTP/1.1\r\n"
9596 "Host: www.example.org\r\n"
9597 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429598 };
9599
9600 // Lastly, the server responds with the actual content.
9601 MockRead data_reads[] = {
9602 MockRead("HTTP/1.0 200 OK\r\n"),
9603 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9604 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069605 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429606 };
9607
[email protected]31a2bfe2010-02-09 08:03:399608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9609 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429611
[email protected]49639fa2011-12-20 23:22:419612 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429613
tfarina42834112016-09-22 13:38:209614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429616
9617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019618 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429619}
9620
bncd16676a2016-07-20 16:23:019621TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429622 HttpRequestInfo request;
9623 request.method = "GET";
bncce36dca22015-04-21 22:11:239624 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429625 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109626 request.traffic_annotation =
9627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429628
danakj1fd259a02016-04-16 03:17:099629 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279631
[email protected]1c773ea12009-04-28 19:58:429632 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239633 MockWrite(
9634 "GET / HTTP/1.1\r\n"
9635 "Host: www.example.org\r\n"
9636 "Connection: keep-alive\r\n"
9637 "Pragma: no-cache\r\n"
9638 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429639 };
9640
9641 // Lastly, the server responds with the actual content.
9642 MockRead data_reads[] = {
9643 MockRead("HTTP/1.0 200 OK\r\n"),
9644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9645 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069646 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429647 };
9648
[email protected]31a2bfe2010-02-09 08:03:399649 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9650 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079651 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429652
[email protected]49639fa2011-12-20 23:22:419653 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429654
tfarina42834112016-09-22 13:38:209655 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429657
9658 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019659 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429660}
9661
bncd16676a2016-07-20 16:23:019662TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429663 HttpRequestInfo request;
9664 request.method = "GET";
bncce36dca22015-04-21 22:11:239665 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429666 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109667 request.traffic_annotation =
9668 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429669
danakj1fd259a02016-04-16 03:17:099670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279672
[email protected]1c773ea12009-04-28 19:58:429673 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239674 MockWrite(
9675 "GET / HTTP/1.1\r\n"
9676 "Host: www.example.org\r\n"
9677 "Connection: keep-alive\r\n"
9678 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429679 };
9680
9681 // Lastly, the server responds with the actual content.
9682 MockRead data_reads[] = {
9683 MockRead("HTTP/1.0 200 OK\r\n"),
9684 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9685 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069686 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429687 };
9688
[email protected]31a2bfe2010-02-09 08:03:399689 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9690 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079691 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429692
[email protected]49639fa2011-12-20 23:22:419693 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429694
tfarina42834112016-09-22 13:38:209695 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429697
9698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019699 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429700}
9701
bncd16676a2016-07-20 16:23:019702TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429703 HttpRequestInfo request;
9704 request.method = "GET";
bncce36dca22015-04-21 22:11:239705 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439706 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:109707 request.traffic_annotation =
9708 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429709
danakj1fd259a02016-04-16 03:17:099710 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279712
[email protected]1c773ea12009-04-28 19:58:429713 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239714 MockWrite(
9715 "GET / HTTP/1.1\r\n"
9716 "Host: www.example.org\r\n"
9717 "Connection: keep-alive\r\n"
9718 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429719 };
9720
9721 // Lastly, the server responds with the actual content.
9722 MockRead data_reads[] = {
9723 MockRead("HTTP/1.0 200 OK\r\n"),
9724 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9725 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069726 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429727 };
9728
[email protected]31a2bfe2010-02-09 08:03:399729 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9730 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079731 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429732
[email protected]49639fa2011-12-20 23:22:419733 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429734
tfarina42834112016-09-22 13:38:209735 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429737
9738 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019739 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429740}
9741
bncd16676a2016-07-20 16:23:019742TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479743 HttpRequestInfo request;
9744 request.method = "GET";
bncce36dca22015-04-21 22:11:239745 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439746 request.extra_headers.SetHeader("referer", "www.foo.com");
9747 request.extra_headers.SetHeader("hEllo", "Kitty");
9748 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:109749 request.traffic_annotation =
9750 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479751
danakj1fd259a02016-04-16 03:17:099752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279754
[email protected]270c6412010-03-29 22:02:479755 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239756 MockWrite(
9757 "GET / HTTP/1.1\r\n"
9758 "Host: www.example.org\r\n"
9759 "Connection: keep-alive\r\n"
9760 "referer: www.foo.com\r\n"
9761 "hEllo: Kitty\r\n"
9762 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479763 };
9764
9765 // Lastly, the server responds with the actual content.
9766 MockRead data_reads[] = {
9767 MockRead("HTTP/1.0 200 OK\r\n"),
9768 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9769 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069770 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479771 };
9772
9773 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9774 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079775 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479776
[email protected]49639fa2011-12-20 23:22:419777 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479778
tfarina42834112016-09-22 13:38:209779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479781
9782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019783 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479784}
9785
bncd16676a2016-07-20 16:23:019786TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279787 HttpRequestInfo request;
9788 request.method = "GET";
bncce36dca22015-04-21 22:11:239789 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109790 request.traffic_annotation =
9791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279792
Lily Houghton8c2f97d2018-01-22 05:06:599793 session_deps_.proxy_resolution_service =
9794 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519795 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079796 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029797
danakj1fd259a02016-04-16 03:17:099798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029800
[email protected]3cd17242009-06-23 02:59:029801 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9802 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9803
9804 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239805 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9806 MockWrite(
9807 "GET / HTTP/1.1\r\n"
9808 "Host: www.example.org\r\n"
9809 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029810
9811 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069812 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029813 MockRead("HTTP/1.0 200 OK\r\n"),
9814 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9815 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069816 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029817 };
9818
[email protected]31a2bfe2010-02-09 08:03:399819 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9820 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079821 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029822
[email protected]49639fa2011-12-20 23:22:419823 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029824
tfarina42834112016-09-22 13:38:209825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029827
9828 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019829 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029830
bnc691fda62016-08-12 00:43:169831 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529832 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029833
tbansal2ecbbc72016-10-06 17:15:479834 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209835 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169836 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209837 TestLoadTimingNotReusedWithPac(load_timing_info,
9838 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9839
[email protected]3cd17242009-06-23 02:59:029840 std::string response_text;
bnc691fda62016-08-12 00:43:169841 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019842 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029843 EXPECT_EQ("Payload", response_text);
9844}
9845
bncd16676a2016-07-20 16:23:019846TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279847 HttpRequestInfo request;
9848 request.method = "GET";
bncce36dca22015-04-21 22:11:239849 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109850 request.traffic_annotation =
9851 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279852
Lily Houghton8c2f97d2018-01-22 05:06:599853 session_deps_.proxy_resolution_service =
9854 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519855 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079856 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029857
danakj1fd259a02016-04-16 03:17:099858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029860
[email protected]3cd17242009-06-23 02:59:029861 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9862 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9863
9864 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239865 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9866 arraysize(write_buffer)),
9867 MockWrite(
9868 "GET / HTTP/1.1\r\n"
9869 "Host: www.example.org\r\n"
9870 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029871
9872 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019873 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9874 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359875 MockRead("HTTP/1.0 200 OK\r\n"),
9876 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9877 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069878 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359879 };
9880
[email protected]31a2bfe2010-02-09 08:03:399881 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9882 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079883 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359884
[email protected]8ddf8322012-02-23 18:08:069885 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359887
[email protected]49639fa2011-12-20 23:22:419888 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359889
tfarina42834112016-09-22 13:38:209890 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359892
9893 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019894 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359895
[email protected]029c83b62013-01-24 05:28:209896 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169897 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209898 TestLoadTimingNotReusedWithPac(load_timing_info,
9899 CONNECT_TIMING_HAS_SSL_TIMES);
9900
bnc691fda62016-08-12 00:43:169901 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529902 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479903 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359904
9905 std::string response_text;
bnc691fda62016-08-12 00:43:169906 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019907 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359908 EXPECT_EQ("Payload", response_text);
9909}
9910
bncd16676a2016-07-20 16:23:019911TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209912 HttpRequestInfo request;
9913 request.method = "GET";
bncce36dca22015-04-21 22:11:239914 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109915 request.traffic_annotation =
9916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209917
Lily Houghton8c2f97d2018-01-22 05:06:599918 session_deps_.proxy_resolution_service =
9919 ProxyResolutionService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519920 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079921 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209922
danakj1fd259a02016-04-16 03:17:099923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209925
9926 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9927 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9928
9929 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239930 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9931 MockWrite(
9932 "GET / HTTP/1.1\r\n"
9933 "Host: www.example.org\r\n"
9934 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209935
9936 MockRead data_reads[] = {
9937 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9938 MockRead("HTTP/1.0 200 OK\r\n"),
9939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9940 MockRead("Payload"),
9941 MockRead(SYNCHRONOUS, OK)
9942 };
9943
9944 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9945 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079946 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209947
9948 TestCompletionCallback callback;
9949
tfarina42834112016-09-22 13:38:209950 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209952
9953 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019954 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209955
bnc691fda62016-08-12 00:43:169956 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529957 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209958
9959 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169960 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209961 TestLoadTimingNotReused(load_timing_info,
9962 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9963
9964 std::string response_text;
bnc691fda62016-08-12 00:43:169965 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019966 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209967 EXPECT_EQ("Payload", response_text);
9968}
9969
bncd16676a2016-07-20 16:23:019970TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279971 HttpRequestInfo request;
9972 request.method = "GET";
bncce36dca22015-04-21 22:11:239973 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109974 request.traffic_annotation =
9975 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279976
Lily Houghton8c2f97d2018-01-22 05:06:599977 session_deps_.proxy_resolution_service =
9978 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519979 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079980 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359981
danakj1fd259a02016-04-16 03:17:099982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359984
[email protected]e0c27be2009-07-15 13:09:359985 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9986 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379987 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239988 0x05, // Version
9989 0x01, // Command (CONNECT)
9990 0x00, // Reserved.
9991 0x03, // Address type (DOMAINNAME).
9992 0x0F, // Length of domain (15)
9993 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9994 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379995 };
[email protected]e0c27be2009-07-15 13:09:359996 const char kSOCKS5OkResponse[] =
9997 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9998
9999 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310000 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10001 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10002 MockWrite(
10003 "GET / HTTP/1.1\r\n"
10004 "Host: www.example.org\r\n"
10005 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510006
10007 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110008 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10009 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510010 MockRead("HTTP/1.0 200 OK\r\n"),
10011 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10012 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610013 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510014 };
10015
[email protected]31a2bfe2010-02-09 08:03:3910016 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10017 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710018 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510019
[email protected]49639fa2011-12-20 23:22:4110020 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510021
tfarina42834112016-09-22 13:38:2010022 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510024
10025 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110026 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510027
bnc691fda62016-08-12 00:43:1610028 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210029 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710030 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510031
[email protected]029c83b62013-01-24 05:28:2010032 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610033 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010034 TestLoadTimingNotReusedWithPac(load_timing_info,
10035 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10036
[email protected]e0c27be2009-07-15 13:09:3510037 std::string response_text;
bnc691fda62016-08-12 00:43:1610038 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110039 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510040 EXPECT_EQ("Payload", response_text);
10041}
10042
bncd16676a2016-07-20 16:23:0110043TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710044 HttpRequestInfo request;
10045 request.method = "GET";
bncce36dca22015-04-21 22:11:2310046 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010047 request.traffic_annotation =
10048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710049
Lily Houghton8c2f97d2018-01-22 05:06:5910050 session_deps_.proxy_resolution_service =
10051 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:5110052 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710053 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510054
danakj1fd259a02016-04-16 03:17:0910055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610056 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510057
[email protected]e0c27be2009-07-15 13:09:3510058 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10059 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710060 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310061 0x05, // Version
10062 0x01, // Command (CONNECT)
10063 0x00, // Reserved.
10064 0x03, // Address type (DOMAINNAME).
10065 0x0F, // Length of domain (15)
10066 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10067 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710068 };
10069
[email protected]e0c27be2009-07-15 13:09:3510070 const char kSOCKS5OkResponse[] =
10071 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10072
10073 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310074 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10075 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10076 arraysize(kSOCKS5OkRequest)),
10077 MockWrite(
10078 "GET / HTTP/1.1\r\n"
10079 "Host: www.example.org\r\n"
10080 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510081
10082 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110083 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10084 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210085 MockRead("HTTP/1.0 200 OK\r\n"),
10086 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10087 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610088 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210089 };
10090
[email protected]31a2bfe2010-02-09 08:03:3910091 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10092 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710093 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210094
[email protected]8ddf8322012-02-23 18:08:0610095 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210097
[email protected]49639fa2011-12-20 23:22:4110098 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210099
tfarina42834112016-09-22 13:38:2010100 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210102
10103 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110104 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210105
bnc691fda62016-08-12 00:43:1610106 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210107 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710108 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210109
[email protected]029c83b62013-01-24 05:28:2010110 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610111 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010112 TestLoadTimingNotReusedWithPac(load_timing_info,
10113 CONNECT_TIMING_HAS_SSL_TIMES);
10114
[email protected]3cd17242009-06-23 02:59:0210115 std::string response_text;
bnc691fda62016-08-12 00:43:1610116 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110117 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210118 EXPECT_EQ("Payload", response_text);
10119}
10120
[email protected]448d4ca52012-03-04 04:12:2310121namespace {
10122
[email protected]04e5be32009-06-26 20:00:3110123// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610124
10125struct GroupNameTest {
10126 std::string proxy_server;
10127 std::string url;
10128 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810129 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610130};
10131
danakj1fd259a02016-04-16 03:17:0910132std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710133 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910134 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610135
bnc525e175a2016-06-20 12:36:4010136 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310137 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110138 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210139 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110140 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210141 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610142 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610143
10144 return session;
10145}
10146
mmenkee65e7af2015-10-13 17:16:4210147int GroupNameTransactionHelper(const std::string& url,
10148 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610149 HttpRequestInfo request;
10150 request.method = "GET";
10151 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1010152 request.traffic_annotation =
10153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610154
bnc691fda62016-08-12 00:43:1610155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710156
[email protected]49639fa2011-12-20 23:22:4110157 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610158
10159 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010160 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610161}
10162
[email protected]448d4ca52012-03-04 04:12:2310163} // namespace
10164
bncd16676a2016-07-20 16:23:0110165TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610166 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310167 {
10168 "", // unused
10169 "http://www.example.org/direct",
10170 "www.example.org:80",
10171 false,
10172 },
10173 {
10174 "", // unused
10175 "http://[2001:1418:13:1::25]/direct",
10176 "[2001:1418:13:1::25]:80",
10177 false,
10178 },
[email protected]04e5be32009-06-26 20:00:3110179
bncce36dca22015-04-21 22:11:2310180 // SSL Tests
10181 {
10182 "", // unused
10183 "https://www.example.org/direct_ssl",
10184 "ssl/www.example.org:443",
10185 true,
10186 },
10187 {
10188 "", // unused
10189 "https://[2001:1418:13:1::25]/direct",
10190 "ssl/[2001:1418:13:1::25]:443",
10191 true,
10192 },
10193 {
10194 "", // unused
bncaa60ff402016-06-22 19:12:4210195 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310196 "ssl/host.with.alternate:443",
10197 true,
10198 },
[email protected]2d731a32010-04-29 01:04:0610199 };
[email protected]2ff8b312010-04-26 22:20:5410200
viettrungluue4a8b882014-10-16 06:17:3810201 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910202 session_deps_.proxy_resolution_service =
10203 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910204 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010205 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610206
mmenkee65e7af2015-10-13 17:16:4210207 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810208 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810209 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310210 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810211 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910212 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210213 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10214 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810215 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610216
10217 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210218 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910219 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810220 EXPECT_EQ(tests[i].expected_group_name,
10221 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910222 } else {
[email protected]e60e47a2010-07-14 03:37:1810223 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810224 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910225 }
10226 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10227 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10228 // When SSL proxy is not in use, socket must be requested from
10229 // |transport_conn_pool|.
10230 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610231 }
[email protected]2d731a32010-04-29 01:04:0610232}
10233
bncd16676a2016-07-20 16:23:0110234TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610235 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310236 {
Matt Menked1eb6d42018-01-17 04:54:0610237 "http_proxy", "http://www.example.org/http_proxy_normal",
10238 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310239 },
[email protected]2d731a32010-04-29 01:04:0610240
bncce36dca22015-04-21 22:11:2310241 // SSL Tests
10242 {
Matt Menked1eb6d42018-01-17 04:54:0610243 "http_proxy", "https://www.example.org/http_connect_ssl",
10244 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310245 },
[email protected]af3490e2010-10-16 21:02:2910246
bncce36dca22015-04-21 22:11:2310247 {
Matt Menked1eb6d42018-01-17 04:54:0610248 "http_proxy", "https://host.with.alternate/direct",
10249 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310250 },
[email protected]45499252013-01-23 17:12:5610251
bncce36dca22015-04-21 22:11:2310252 {
Matt Menked1eb6d42018-01-17 04:54:0610253 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10254 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310255 },
[email protected]2d731a32010-04-29 01:04:0610256 };
10257
viettrungluue4a8b882014-10-16 06:17:3810258 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910259 session_deps_.proxy_resolution_service =
10260 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910261 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010262 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610263
mmenkee65e7af2015-10-13 17:16:4210264 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610265
[email protected]e60e47a2010-07-14 03:37:1810266 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310267 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410268 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310269 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410270 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910271 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910272 mock_pool_manager->SetSocketPoolForHTTPProxy(
10273 proxy_host, base::WrapUnique(http_proxy_pool));
10274 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10275 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810276 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610277
10278 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210279 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810280 if (tests[i].ssl)
10281 EXPECT_EQ(tests[i].expected_group_name,
10282 ssl_conn_pool->last_group_name_received());
10283 else
10284 EXPECT_EQ(tests[i].expected_group_name,
10285 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610286 }
[email protected]2d731a32010-04-29 01:04:0610287}
10288
bncd16676a2016-07-20 16:23:0110289TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610290 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310291 {
10292 "socks4://socks_proxy:1080",
10293 "http://www.example.org/socks4_direct",
10294 "socks4/www.example.org:80",
10295 false,
10296 },
10297 {
10298 "socks5://socks_proxy:1080",
10299 "http://www.example.org/socks5_direct",
10300 "socks5/www.example.org:80",
10301 false,
10302 },
[email protected]2d731a32010-04-29 01:04:0610303
bncce36dca22015-04-21 22:11:2310304 // SSL Tests
10305 {
10306 "socks4://socks_proxy:1080",
10307 "https://www.example.org/socks4_ssl",
10308 "socks4/ssl/www.example.org:443",
10309 true,
10310 },
10311 {
10312 "socks5://socks_proxy:1080",
10313 "https://www.example.org/socks5_ssl",
10314 "socks5/ssl/www.example.org:443",
10315 true,
10316 },
[email protected]af3490e2010-10-16 21:02:2910317
bncce36dca22015-04-21 22:11:2310318 {
10319 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210320 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310321 "socks4/ssl/host.with.alternate:443",
10322 true,
10323 },
[email protected]04e5be32009-06-26 20:00:3110324 };
10325
viettrungluue4a8b882014-10-16 06:17:3810326 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910327 session_deps_.proxy_resolution_service =
10328 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910329 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010330 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210331
mmenkee65e7af2015-10-13 17:16:4210332 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110333
[email protected]e60e47a2010-07-14 03:37:1810334 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310335 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410336 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310337 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410338 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910339 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910340 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10341 proxy_host, base::WrapUnique(socks_conn_pool));
10342 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10343 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810344 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110345
bnc691fda62016-08-12 00:43:1610346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110347
[email protected]2d731a32010-04-29 01:04:0610348 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210349 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810350 if (tests[i].ssl)
10351 EXPECT_EQ(tests[i].expected_group_name,
10352 ssl_conn_pool->last_group_name_received());
10353 else
10354 EXPECT_EQ(tests[i].expected_group_name,
10355 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110356 }
10357}
10358
bncd16676a2016-07-20 16:23:0110359TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710360 HttpRequestInfo request;
10361 request.method = "GET";
bncce36dca22015-04-21 22:11:2310362 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010363 request.traffic_annotation =
10364 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710365
Lily Houghton8c2f97d2018-01-22 05:06:5910366 session_deps_.proxy_resolution_service =
10367 ProxyResolutionService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:3210368
[email protected]69719062010-01-05 20:09:2110369 // This simulates failure resolving all hostnames; that means we will fail
10370 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710371 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210372
danakj1fd259a02016-04-16 03:17:0910373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510375
[email protected]49639fa2011-12-20 23:22:4110376 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510377
tfarina42834112016-09-22 13:38:2010378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510380
[email protected]9172a982009-06-06 00:30:2510381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110382 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510383}
10384
[email protected]685af592010-05-11 19:31:2410385// Base test to make sure that when the load flags for a request specify to
10386// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210387void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710388 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710389 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010390 HttpRequestInfo request_info;
10391 request_info.method = "GET";
10392 request_info.load_flags = load_flags;
10393 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010394 request_info.traffic_annotation =
10395 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710396
[email protected]a2c2fb92009-07-18 07:31:0410397 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910398 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210399
danakj1fd259a02016-04-16 03:17:0910400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610401 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810402
bncce36dca22015-04-21 22:11:2310403 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810404 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910405 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010406 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710407 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310408 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010409 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010410 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110413 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810414
10415 // Verify that it was added to host cache, by doing a subsequent async lookup
10416 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010417 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710418 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310419 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010420 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010421 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110422 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810423
bncce36dca22015-04-21 22:11:2310424 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810425 // we can tell if the next lookup hit the cache, or the "network".
10426 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310427 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810428
10429 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10430 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610431 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910432 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710433 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810434
[email protected]3b9cca42009-06-16 01:08:2810435 // Run the request.
tfarina42834112016-09-22 13:38:2010436 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110437 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110438 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810439
10440 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310441 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110442 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810443}
10444
[email protected]685af592010-05-11 19:31:2410445// There are multiple load flags that should trigger the host cache bypass.
10446// Test each in isolation:
bncd16676a2016-07-20 16:23:0110447TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410448 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10449}
10450
bncd16676a2016-07-20 16:23:0110451TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410452 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10453}
10454
bncd16676a2016-07-20 16:23:0110455TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410456 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10457}
10458
[email protected]0877e3d2009-10-17 22:29:5710459// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110460TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710461 HttpRequestInfo request;
10462 request.method = "GET";
10463 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010464 request.traffic_annotation =
10465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710466
10467 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610468 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710469 };
[email protected]31a2bfe2010-02-09 08:03:3910470 StaticSocketDataProvider data(NULL, 0,
10471 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710472 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710474
[email protected]49639fa2011-12-20 23:22:4110475 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710476
bnc691fda62016-08-12 00:43:1610477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710478
tfarina42834112016-09-22 13:38:2010479 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710481
10482 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110483 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910484
10485 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610486 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910487 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710488}
10489
zmo9528c9f42015-08-04 22:12:0810490// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110491TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710492 HttpRequestInfo request;
10493 request.method = "GET";
10494 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010495 request.traffic_annotation =
10496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710497
10498 MockRead data_reads[] = {
10499 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610500 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710501 };
10502
[email protected]31a2bfe2010-02-09 08:03:3910503 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710504 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710506
[email protected]49639fa2011-12-20 23:22:4110507 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710508
bnc691fda62016-08-12 00:43:1610509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710510
tfarina42834112016-09-22 13:38:2010511 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710513
10514 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110515 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810516
bnc691fda62016-08-12 00:43:1610517 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210518 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810519
wezca1070932016-05-26 20:30:5210520 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810521 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10522
10523 std::string response_data;
bnc691fda62016-08-12 00:43:1610524 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110525 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810526 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910527
10528 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610529 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910530 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710531}
10532
10533// Make sure that a dropped connection while draining the body for auth
10534// restart does the right thing.
bncd16676a2016-07-20 16:23:0110535TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710536 HttpRequestInfo request;
10537 request.method = "GET";
bncce36dca22015-04-21 22:11:2310538 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010539 request.traffic_annotation =
10540 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710541
10542 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310543 MockWrite(
10544 "GET / HTTP/1.1\r\n"
10545 "Host: www.example.org\r\n"
10546 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710547 };
10548
10549 MockRead data_reads1[] = {
10550 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10551 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10553 MockRead("Content-Length: 14\r\n\r\n"),
10554 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610555 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710556 };
10557
[email protected]31a2bfe2010-02-09 08:03:3910558 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10559 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710561
bnc691fda62016-08-12 00:43:1610562 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710563 // be issuing -- the final header line contains the credentials.
10564 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310565 MockWrite(
10566 "GET / HTTP/1.1\r\n"
10567 "Host: www.example.org\r\n"
10568 "Connection: keep-alive\r\n"
10569 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710570 };
10571
10572 // Lastly, the server responds with the actual content.
10573 MockRead data_reads2[] = {
10574 MockRead("HTTP/1.1 200 OK\r\n"),
10575 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10576 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610577 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710578 };
10579
[email protected]31a2bfe2010-02-09 08:03:3910580 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10581 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710582 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710584
[email protected]49639fa2011-12-20 23:22:4110585 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710586
bnc691fda62016-08-12 00:43:1610587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010588
tfarina42834112016-09-22 13:38:2010589 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710591
10592 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110593 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710594
bnc691fda62016-08-12 00:43:1610595 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210596 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410597 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710598
[email protected]49639fa2011-12-20 23:22:4110599 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710600
bnc691fda62016-08-12 00:43:1610601 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710603
10604 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110605 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710606
bnc691fda62016-08-12 00:43:1610607 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210608 ASSERT_TRUE(response);
10609 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710610 EXPECT_EQ(100, response->headers->GetContentLength());
10611}
10612
10613// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110614TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Lily Houghton8c2f97d2018-01-22 05:06:5910615 session_deps_.proxy_resolution_service =
10616 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710617
10618 HttpRequestInfo request;
10619 request.method = "GET";
bncce36dca22015-04-21 22:11:2310620 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010621 request.traffic_annotation =
10622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710623
10624 MockRead proxy_reads[] = {
10625 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610626 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710627 };
10628
[email protected]31a2bfe2010-02-09 08:03:3910629 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610630 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710631
[email protected]bb88e1d32013-05-03 23:11:0710632 session_deps_.socket_factory->AddSocketDataProvider(&data);
10633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710634
[email protected]49639fa2011-12-20 23:22:4110635 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710636
[email protected]bb88e1d32013-05-03 23:11:0710637 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710638
danakj1fd259a02016-04-16 03:17:0910639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710641
tfarina42834112016-09-22 13:38:2010642 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710644
10645 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110646 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710647}
10648
bncd16676a2016-07-20 16:23:0110649TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610650 HttpRequestInfo request;
10651 request.method = "GET";
bncce36dca22015-04-21 22:11:2310652 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010653 request.traffic_annotation =
10654 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610655
danakj1fd259a02016-04-16 03:17:0910656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710658
[email protected]e22e1362009-11-23 21:31:1210659 MockRead data_reads[] = {
10660 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610661 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210662 };
[email protected]9492e4a2010-02-24 00:58:4610663
10664 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710665 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610666
[email protected]49639fa2011-12-20 23:22:4110667 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610668
tfarina42834112016-09-22 13:38:2010669 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610671
robpercival214763f2016-07-01 23:27:0110672 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610673
bnc691fda62016-08-12 00:43:1610674 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210675 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610676
wezca1070932016-05-26 20:30:5210677 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610678 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10679
10680 std::string response_data;
bnc691fda62016-08-12 00:43:1610681 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110682 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210683}
10684
bncd16676a2016-07-20 16:23:0110685TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510686 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210687 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410688 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110689 UploadFileElementReader::ScopedOverridingContentLengthForTests
10690 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310691
danakj1fd259a02016-04-16 03:17:0910692 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910693 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410694 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710695 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210696 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710697
10698 HttpRequestInfo request;
10699 request.method = "POST";
bncce36dca22015-04-21 22:11:2310700 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710701 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010702 request.traffic_annotation =
10703 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710704
danakj1fd259a02016-04-16 03:17:0910705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310707
10708 MockRead data_reads[] = {
10709 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10710 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610711 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310712 };
[email protected]31a2bfe2010-02-09 08:03:3910713 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710714 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310715
[email protected]49639fa2011-12-20 23:22:4110716 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310717
tfarina42834112016-09-22 13:38:2010718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310720
10721 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110722 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310723
bnc691fda62016-08-12 00:43:1610724 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210725 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310726
maksim.sisove869bf52016-06-23 17:11:5210727 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310728
[email protected]dd3aa792013-07-16 19:10:2310729 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310730}
10731
bncd16676a2016-07-20 16:23:0110732TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510733 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210734 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610735 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810736 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10737 base::WriteFile(temp_file, temp_file_content.c_str(),
10738 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110739 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610740
danakj1fd259a02016-04-16 03:17:0910741 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910742 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410743 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710744 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210745 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710746
10747 HttpRequestInfo request;
10748 request.method = "POST";
bncce36dca22015-04-21 22:11:2310749 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710750 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010751 request.traffic_annotation =
10752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710753
[email protected]999dd8c2013-11-12 06:45:5410754 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610757
[email protected]999dd8c2013-11-12 06:45:5410758 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710759 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610760
[email protected]49639fa2011-12-20 23:22:4110761 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610762
tfarina42834112016-09-22 13:38:2010763 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610765
10766 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110767 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610768
[email protected]dd3aa792013-07-16 19:10:2310769 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610770}
10771
bncd16676a2016-07-20 16:23:0110772TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310773 class FakeUploadElementReader : public UploadElementReader {
10774 public:
Chris Watkins7a41d3552017-12-01 02:13:2710775 FakeUploadElementReader() = default;
10776 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310777
Matt Menkecc1d3a902018-02-05 18:27:3310778 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310779
10780 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310781 int Init(CompletionOnceCallback callback) override {
10782 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310783 return ERR_IO_PENDING;
10784 }
avibf0746c2015-12-09 19:53:1410785 uint64_t GetContentLength() const override { return 0; }
10786 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010787 int Read(IOBuffer* buf,
10788 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310789 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310790 return ERR_FAILED;
10791 }
10792
10793 private:
Matt Menkecc1d3a902018-02-05 18:27:3310794 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310795 };
10796
10797 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910798 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10799 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210800 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310801
10802 HttpRequestInfo request;
10803 request.method = "POST";
bncce36dca22015-04-21 22:11:2310804 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310805 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010806 request.traffic_annotation =
10807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310808
danakj1fd259a02016-04-16 03:17:0910809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810810 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910811 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310812
10813 StaticSocketDataProvider data;
10814 session_deps_.socket_factory->AddSocketDataProvider(&data);
10815
10816 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010817 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510819 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310820
10821 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310822 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10823 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310824
10825 // Return Init()'s result after the transaction gets destroyed.
10826 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310827 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310828}
10829
[email protected]aeefc9e82010-02-19 16:18:2710830// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110831TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710832 HttpRequestInfo request;
10833 request.method = "GET";
bncce36dca22015-04-21 22:11:2310834 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010835 request.traffic_annotation =
10836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710837
10838 // First transaction will request a resource and receive a Basic challenge
10839 // with realm="first_realm".
10840 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310841 MockWrite(
10842 "GET / HTTP/1.1\r\n"
10843 "Host: www.example.org\r\n"
10844 "Connection: keep-alive\r\n"
10845 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710846 };
10847 MockRead data_reads1[] = {
10848 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10849 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10850 "\r\n"),
10851 };
10852
bnc691fda62016-08-12 00:43:1610853 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710854 // for first_realm. The server will reject and provide a challenge with
10855 // second_realm.
10856 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310857 MockWrite(
10858 "GET / HTTP/1.1\r\n"
10859 "Host: www.example.org\r\n"
10860 "Connection: keep-alive\r\n"
10861 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10862 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710863 };
10864 MockRead data_reads2[] = {
10865 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10866 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10867 "\r\n"),
10868 };
10869
10870 // This again fails, and goes back to first_realm. Make sure that the
10871 // entry is removed from cache.
10872 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310873 MockWrite(
10874 "GET / HTTP/1.1\r\n"
10875 "Host: www.example.org\r\n"
10876 "Connection: keep-alive\r\n"
10877 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10878 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710879 };
10880 MockRead data_reads3[] = {
10881 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10882 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10883 "\r\n"),
10884 };
10885
10886 // Try one last time (with the correct password) and get the resource.
10887 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310888 MockWrite(
10889 "GET / HTTP/1.1\r\n"
10890 "Host: www.example.org\r\n"
10891 "Connection: keep-alive\r\n"
10892 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10893 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710894 };
10895 MockRead data_reads4[] = {
10896 MockRead("HTTP/1.1 200 OK\r\n"
10897 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010898 "Content-Length: 5\r\n"
10899 "\r\n"
10900 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710901 };
10902
10903 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10904 data_writes1, arraysize(data_writes1));
10905 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10906 data_writes2, arraysize(data_writes2));
10907 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10908 data_writes3, arraysize(data_writes3));
10909 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10910 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710911 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10912 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10913 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10914 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710915
[email protected]49639fa2011-12-20 23:22:4110916 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710917
danakj1fd259a02016-04-16 03:17:0910918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010920
[email protected]aeefc9e82010-02-19 16:18:2710921 // Issue the first request with Authorize headers. There should be a
10922 // password prompt for first_realm waiting to be filled in after the
10923 // transaction completes.
tfarina42834112016-09-22 13:38:2010924 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710926 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110927 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210929 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410930 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210931 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410932 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310933 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410934 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910935 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710936
10937 // Issue the second request with an incorrect password. There should be a
10938 // password prompt for second_realm waiting to be filled in after the
10939 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110940 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610941 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10942 callback2.callback());
robpercival214763f2016-07-01 23:27:0110943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710944 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110945 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610946 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210947 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410948 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210949 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410950 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310951 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410952 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910953 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710954
10955 // Issue the third request with another incorrect password. There should be
10956 // a password prompt for first_realm waiting to be filled in. If the password
10957 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10958 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110959 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610960 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10961 callback3.callback());
robpercival214763f2016-07-01 23:27:0110962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710963 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110964 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610965 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210966 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410967 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210968 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410969 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310970 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410971 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910972 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710973
10974 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110975 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610976 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10977 callback4.callback());
robpercival214763f2016-07-01 23:27:0110978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710979 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110980 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610981 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210982 ASSERT_TRUE(response);
10983 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710984}
10985
Bence Béky230ac612017-08-30 19:17:0810986// Regression test for https://crbug.com/754395.
10987TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10988 MockRead data_reads[] = {
10989 MockRead("HTTP/1.1 200 OK\r\n"),
10990 MockRead(kAlternativeServiceHttpHeader),
10991 MockRead("\r\n"),
10992 MockRead("hello world"),
10993 MockRead(SYNCHRONOUS, OK),
10994 };
10995
10996 HttpRequestInfo request;
10997 request.method = "GET";
10998 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010999 request.traffic_annotation =
11000 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811001
11002 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11003 session_deps_.socket_factory->AddSocketDataProvider(&data);
11004
11005 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911006 ssl.ssl_info.cert =
11007 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11008 ASSERT_TRUE(ssl.ssl_info.cert);
11009 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11011
11012 TestCompletionCallback callback;
11013
11014 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11016
11017 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11019
11020 url::SchemeHostPort test_server(request.url);
11021 HttpServerProperties* http_server_properties =
11022 session->http_server_properties();
11023 EXPECT_TRUE(
11024 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11025
11026 EXPECT_THAT(callback.WaitForResult(), IsOk());
11027
11028 const HttpResponseInfo* response = trans.GetResponseInfo();
11029 ASSERT_TRUE(response);
11030 ASSERT_TRUE(response->headers);
11031 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11032 EXPECT_FALSE(response->was_fetched_via_spdy);
11033 EXPECT_FALSE(response->was_alpn_negotiated);
11034
11035 std::string response_data;
11036 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11037 EXPECT_EQ("hello world", response_data);
11038
11039 EXPECT_TRUE(
11040 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11041}
11042
bncd16676a2016-07-20 16:23:0111043TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211044 MockRead data_reads[] = {
11045 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311046 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211047 MockRead("\r\n"),
11048 MockRead("hello world"),
11049 MockRead(SYNCHRONOUS, OK),
11050 };
11051
11052 HttpRequestInfo request;
11053 request.method = "GET";
bncb26024382016-06-29 02:39:4511054 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011055 request.traffic_annotation =
11056 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211057
11058 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211059 session_deps_.socket_factory->AddSocketDataProvider(&data);
11060
bncb26024382016-06-29 02:39:4511061 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911062 ssl.ssl_info.cert =
11063 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11064 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11066
bncc958faa2015-07-31 18:14:5211067 TestCompletionCallback callback;
11068
danakj1fd259a02016-04-16 03:17:0911069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211071
tfarina42834112016-09-22 13:38:2011072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211074
bncb26024382016-06-29 02:39:4511075 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011076 HttpServerProperties* http_server_properties =
11077 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411078 EXPECT_TRUE(
11079 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211080
robpercival214763f2016-07-01 23:27:0111081 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211082
bnc691fda62016-08-12 00:43:1611083 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211084 ASSERT_TRUE(response);
11085 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11087 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211088 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211089
11090 std::string response_data;
bnc691fda62016-08-12 00:43:1611091 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211092 EXPECT_EQ("hello world", response_data);
11093
zhongyic4de03032017-05-19 04:07:3411094 AlternativeServiceInfoVector alternative_service_info_vector =
11095 http_server_properties->GetAlternativeServiceInfos(test_server);
11096 ASSERT_EQ(1u, alternative_service_info_vector.size());
11097 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11098 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411099 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211100}
11101
bnce3dd56f2016-06-01 10:37:1111102// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111103TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111104 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111105 MockRead data_reads[] = {
11106 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311107 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111108 MockRead("\r\n"),
11109 MockRead("hello world"),
11110 MockRead(SYNCHRONOUS, OK),
11111 };
11112
11113 HttpRequestInfo request;
11114 request.method = "GET";
11115 request.url = GURL("http://www.example.org/");
11116 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011117 request.traffic_annotation =
11118 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111119
11120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11121 session_deps_.socket_factory->AddSocketDataProvider(&data);
11122
11123 TestCompletionCallback callback;
11124
11125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111127
11128 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011129 HttpServerProperties* http_server_properties =
11130 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411131 EXPECT_TRUE(
11132 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111133
tfarina42834112016-09-22 13:38:2011134 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111135 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11136 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111137
bnc691fda62016-08-12 00:43:1611138 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111139 ASSERT_TRUE(response);
11140 ASSERT_TRUE(response->headers);
11141 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11142 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211143 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111144
11145 std::string response_data;
bnc691fda62016-08-12 00:43:1611146 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111147 EXPECT_EQ("hello world", response_data);
11148
zhongyic4de03032017-05-19 04:07:3411149 EXPECT_TRUE(
11150 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111151}
11152
bnca86731e2017-04-17 12:31:2811153// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511154// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111155TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511156 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811157 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511158
bnc8bef8da22016-05-30 01:28:2511159 HttpRequestInfo request;
11160 request.method = "GET";
bncb26024382016-06-29 02:39:4511161 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511162 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011163 request.traffic_annotation =
11164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511165
11166 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11167 StaticSocketDataProvider first_data;
11168 first_data.set_connect_data(mock_connect);
11169 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511170 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611171 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511173
11174 MockRead data_reads[] = {
11175 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11176 MockRead(ASYNC, OK),
11177 };
11178 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11179 0);
11180 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11181
11182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11183
bnc525e175a2016-06-20 12:36:4011184 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511185 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111186 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11187 444);
bnc8bef8da22016-05-30 01:28:2511188 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111189 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511190 url::SchemeHostPort(request.url), alternative_service, expiration);
11191
bnc691fda62016-08-12 00:43:1611192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511193 TestCompletionCallback callback;
11194
tfarina42834112016-09-22 13:38:2011195 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511196 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111197 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511198}
11199
bnce3dd56f2016-06-01 10:37:1111200// Regression test for https://crbug.com/615497:
11201// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111202TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111203 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111204 HttpRequestInfo request;
11205 request.method = "GET";
11206 request.url = GURL("http://www.example.org/");
11207 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011208 request.traffic_annotation =
11209 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111210
11211 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11212 StaticSocketDataProvider first_data;
11213 first_data.set_connect_data(mock_connect);
11214 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11215
11216 MockRead data_reads[] = {
11217 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11218 MockRead(ASYNC, OK),
11219 };
11220 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11221 0);
11222 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11223
11224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11225
bnc525e175a2016-06-20 12:36:4011226 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111227 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111228 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111229 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111230 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111231 url::SchemeHostPort(request.url), alternative_service, expiration);
11232
bnc691fda62016-08-12 00:43:1611233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111234 TestCompletionCallback callback;
11235
tfarina42834112016-09-22 13:38:2011236 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111237 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111238 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111239}
11240
bncd16676a2016-07-20 16:23:0111241TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811242 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011244 HttpServerProperties* http_server_properties =
11245 session->http_server_properties();
bncb26024382016-06-29 02:39:4511246 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111247 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811248 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111249 http_server_properties->SetQuicAlternativeService(
11250 test_server, alternative_service, expiration,
11251 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411252 EXPECT_EQ(
11253 1u,
11254 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811255
11256 // Send a clear header.
11257 MockRead data_reads[] = {
11258 MockRead("HTTP/1.1 200 OK\r\n"),
11259 MockRead("Alt-Svc: clear\r\n"),
11260 MockRead("\r\n"),
11261 MockRead("hello world"),
11262 MockRead(SYNCHRONOUS, OK),
11263 };
11264 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
11265 session_deps_.socket_factory->AddSocketDataProvider(&data);
11266
bncb26024382016-06-29 02:39:4511267 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911268 ssl.ssl_info.cert =
11269 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11270 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11272
bnc4f575852015-10-14 18:35:0811273 HttpRequestInfo request;
11274 request.method = "GET";
bncb26024382016-06-29 02:39:4511275 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011276 request.traffic_annotation =
11277 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811278
11279 TestCompletionCallback callback;
11280
bnc691fda62016-08-12 00:43:1611281 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811282
tfarina42834112016-09-22 13:38:2011283 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111284 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811285
bnc691fda62016-08-12 00:43:1611286 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211287 ASSERT_TRUE(response);
11288 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811289 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11290 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211291 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811292
11293 std::string response_data;
bnc691fda62016-08-12 00:43:1611294 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811295 EXPECT_EQ("hello world", response_data);
11296
zhongyic4de03032017-05-19 04:07:3411297 EXPECT_TRUE(
11298 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811299}
11300
bncd16676a2016-07-20 16:23:0111301TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211302 MockRead data_reads[] = {
11303 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311304 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11305 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211306 MockRead("hello world"),
11307 MockRead(SYNCHRONOUS, OK),
11308 };
11309
11310 HttpRequestInfo request;
11311 request.method = "GET";
bncb26024382016-06-29 02:39:4511312 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011313 request.traffic_annotation =
11314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211315
11316 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211317 session_deps_.socket_factory->AddSocketDataProvider(&data);
11318
bncb26024382016-06-29 02:39:4511319 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911320 ssl.ssl_info.cert =
11321 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11322 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511323 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11324
bncc958faa2015-07-31 18:14:5211325 TestCompletionCallback callback;
11326
danakj1fd259a02016-04-16 03:17:0911327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611328 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211329
tfarina42834112016-09-22 13:38:2011330 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211332
bncb26024382016-06-29 02:39:4511333 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011334 HttpServerProperties* http_server_properties =
11335 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411336 EXPECT_TRUE(
11337 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211338
robpercival214763f2016-07-01 23:27:0111339 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211340
bnc691fda62016-08-12 00:43:1611341 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211342 ASSERT_TRUE(response);
11343 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211344 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11345 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211346 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211347
11348 std::string response_data;
bnc691fda62016-08-12 00:43:1611349 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211350 EXPECT_EQ("hello world", response_data);
11351
zhongyic4de03032017-05-19 04:07:3411352 AlternativeServiceInfoVector alternative_service_info_vector =
11353 http_server_properties->GetAlternativeServiceInfos(test_server);
11354 ASSERT_EQ(2u, alternative_service_info_vector.size());
11355
11356 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11357 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411358 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411359 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11360 1234);
11361 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411362 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211363}
11364
bncd16676a2016-07-20 16:23:0111365TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611366 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211367 HostPortPair alternative("alternative.example.org", 443);
11368 std::string origin_url = "https://origin.example.org:443";
11369 std::string alternative_url = "https://alternative.example.org:443";
11370
11371 // Negotiate HTTP/1.1 with alternative.example.org.
11372 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611373 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11375
11376 // HTTP/1.1 data for request.
11377 MockWrite http_writes[] = {
11378 MockWrite("GET / HTTP/1.1\r\n"
11379 "Host: alternative.example.org\r\n"
11380 "Connection: keep-alive\r\n\r\n"),
11381 };
11382
11383 MockRead http_reads[] = {
11384 MockRead("HTTP/1.1 200 OK\r\n"
11385 "Content-Type: text/html; charset=iso-8859-1\r\n"
11386 "Content-Length: 40\r\n\r\n"
11387 "first HTTP/1.1 response from alternative"),
11388 };
11389 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11390 http_writes, arraysize(http_writes));
11391 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11392
11393 StaticSocketDataProvider data_refused;
11394 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11395 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11396
zhongyi3d4a55e72016-04-22 20:36:4611397 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911398 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011399 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211400 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111401 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211402 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111403 http_server_properties->SetQuicAlternativeService(
11404 server, alternative_service, expiration,
11405 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211406 // Mark the QUIC alternative service as broken.
11407 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11408
zhongyi48704c182015-12-07 07:52:0211409 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211411 request.method = "GET";
11412 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011413 request.traffic_annotation =
11414 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11415
zhongyi48704c182015-12-07 07:52:0211416 TestCompletionCallback callback;
11417 NetErrorDetails details;
11418 EXPECT_FALSE(details.quic_broken);
11419
tfarina42834112016-09-22 13:38:2011420 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611421 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211422 EXPECT_TRUE(details.quic_broken);
11423}
11424
bncd16676a2016-07-20 16:23:0111425TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611426 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211427 HostPortPair alternative1("alternative1.example.org", 443);
11428 HostPortPair alternative2("alternative2.example.org", 443);
11429 std::string origin_url = "https://origin.example.org:443";
11430 std::string alternative_url1 = "https://alternative1.example.org:443";
11431 std::string alternative_url2 = "https://alternative2.example.org:443";
11432
11433 // Negotiate HTTP/1.1 with alternative1.example.org.
11434 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611435 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11437
11438 // HTTP/1.1 data for request.
11439 MockWrite http_writes[] = {
11440 MockWrite("GET / HTTP/1.1\r\n"
11441 "Host: alternative1.example.org\r\n"
11442 "Connection: keep-alive\r\n\r\n"),
11443 };
11444
11445 MockRead http_reads[] = {
11446 MockRead("HTTP/1.1 200 OK\r\n"
11447 "Content-Type: text/html; charset=iso-8859-1\r\n"
11448 "Content-Length: 40\r\n\r\n"
11449 "first HTTP/1.1 response from alternative1"),
11450 };
11451 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11452 http_writes, arraysize(http_writes));
11453 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11454
11455 StaticSocketDataProvider data_refused;
11456 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11457 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11458
danakj1fd259a02016-04-16 03:17:0911459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011460 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211461 session->http_server_properties();
11462
zhongyi3d4a55e72016-04-22 20:36:4611463 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211464 AlternativeServiceInfoVector alternative_service_info_vector;
11465 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11466
bnc3472afd2016-11-17 15:27:2111467 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111468 alternative_service_info_vector.push_back(
11469 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11470 alternative_service1, expiration,
11471 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111472 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111473 alternative_service_info_vector.push_back(
11474 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11475 alternative_service2, expiration,
11476 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211477
11478 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611479 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211480
11481 // Mark one of the QUIC alternative service as broken.
11482 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411483 EXPECT_EQ(2u,
11484 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211485
zhongyi48704c182015-12-07 07:52:0211486 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611487 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211488 request.method = "GET";
11489 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011490 request.traffic_annotation =
11491 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11492
zhongyi48704c182015-12-07 07:52:0211493 TestCompletionCallback callback;
11494 NetErrorDetails details;
11495 EXPECT_FALSE(details.quic_broken);
11496
tfarina42834112016-09-22 13:38:2011497 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611498 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211499 EXPECT_FALSE(details.quic_broken);
11500}
11501
bncd16676a2016-07-20 16:23:0111502TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211503 HttpRequestInfo request;
11504 request.method = "GET";
bncb26024382016-06-29 02:39:4511505 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011506 request.traffic_annotation =
11507 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211508
[email protected]d973e99a2012-02-17 21:02:3611509 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211510 StaticSocketDataProvider first_data;
11511 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711512 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511513 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611514 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511515 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211516
11517 MockRead data_reads[] = {
11518 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11519 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611520 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211521 };
11522 StaticSocketDataProvider second_data(
11523 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711524 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211525
danakj1fd259a02016-04-16 03:17:0911526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211527
bnc525e175a2016-06-20 12:36:4011528 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311529 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611530 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111531 // Port must be < 1024, or the header will be ignored (since initial port was
11532 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111533 // Port is ignored by MockConnect anyway.
11534 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11535 666);
bnc7dc7e1b42015-07-28 14:43:1211536 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111537 http_server_properties->SetHttp2AlternativeService(
11538 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211539
bnc691fda62016-08-12 00:43:1611540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111541 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211542
tfarina42834112016-09-22 13:38:2011543 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11545 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211546
bnc691fda62016-08-12 00:43:1611547 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211548 ASSERT_TRUE(response);
11549 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211550 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11551
11552 std::string response_data;
bnc691fda62016-08-12 00:43:1611553 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211554 EXPECT_EQ("hello world", response_data);
11555
zhongyic4de03032017-05-19 04:07:3411556 const AlternativeServiceInfoVector alternative_service_info_vector =
11557 http_server_properties->GetAlternativeServiceInfos(server);
11558 ASSERT_EQ(1u, alternative_service_info_vector.size());
11559 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411560 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411561 EXPECT_TRUE(
11562 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211563}
11564
bnc55ff9da2015-08-19 18:42:3511565// Ensure that we are not allowed to redirect traffic via an alternate protocol
11566// to an unrestricted (port >= 1024) when the original traffic was on a
11567// restricted port (port < 1024). Ensure that we can redirect in all other
11568// cases.
bncd16676a2016-07-20 16:23:0111569TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111570 HttpRequestInfo restricted_port_request;
11571 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511572 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111573 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011574 restricted_port_request.traffic_annotation =
11575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111576
[email protected]d973e99a2012-02-17 21:02:3611577 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111578 StaticSocketDataProvider first_data;
11579 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711580 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111581
11582 MockRead data_reads[] = {
11583 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11584 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611585 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111586 };
11587 StaticSocketDataProvider second_data(
11588 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711589 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511590 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611591 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111593
danakj1fd259a02016-04-16 03:17:0911594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111595
bnc525e175a2016-06-20 12:36:4011596 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311597 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111598 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111599 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11600 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211601 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111602 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611603 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011604 expiration);
[email protected]3912662a32011-10-04 00:51:1111605
bnc691fda62016-08-12 00:43:1611606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111607 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111608
tfarina42834112016-09-22 13:38:2011609 int rv = trans.Start(&restricted_port_request, callback.callback(),
11610 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111612 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111613 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911614}
[email protected]3912662a32011-10-04 00:51:1111615
bnc55ff9da2015-08-19 18:42:3511616// Ensure that we are allowed to redirect traffic via an alternate protocol to
11617// an unrestricted (port >= 1024) when the original traffic was on a restricted
11618// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111619TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711620 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911621
11622 HttpRequestInfo restricted_port_request;
11623 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511624 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911625 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011626 restricted_port_request.traffic_annotation =
11627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911628
11629 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11630 StaticSocketDataProvider first_data;
11631 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711632 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911633
11634 MockRead data_reads[] = {
11635 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11636 MockRead("hello world"),
11637 MockRead(ASYNC, OK),
11638 };
11639 StaticSocketDataProvider second_data(
11640 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711641 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511642 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611643 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911645
danakj1fd259a02016-04-16 03:17:0911646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911647
bnc525e175a2016-06-20 12:36:4011648 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911649 session->http_server_properties();
11650 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111651 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11652 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211653 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111654 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611655 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011656 expiration);
[email protected]c54c6962013-02-01 04:53:1911657
bnc691fda62016-08-12 00:43:1611658 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911659 TestCompletionCallback callback;
11660
tfarina42834112016-09-22 13:38:2011661 EXPECT_EQ(ERR_IO_PENDING,
11662 trans.Start(&restricted_port_request, callback.callback(),
11663 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911664 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111665 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111666}
11667
bnc55ff9da2015-08-19 18:42:3511668// Ensure that we are not allowed to redirect traffic via an alternate protocol
11669// to an unrestricted (port >= 1024) when the original traffic was on a
11670// restricted port (port < 1024). Ensure that we can redirect in all other
11671// cases.
bncd16676a2016-07-20 16:23:0111672TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111673 HttpRequestInfo restricted_port_request;
11674 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511675 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111676 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011677 restricted_port_request.traffic_annotation =
11678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111679
[email protected]d973e99a2012-02-17 21:02:3611680 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111681 StaticSocketDataProvider first_data;
11682 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711683 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111684
11685 MockRead data_reads[] = {
11686 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11687 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611688 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111689 };
11690 StaticSocketDataProvider second_data(
11691 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711692 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111693
bncb26024382016-06-29 02:39:4511694 SSLSocketDataProvider ssl(ASYNC, OK);
11695 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11696
danakj1fd259a02016-04-16 03:17:0911697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111698
bnc525e175a2016-06-20 12:36:4011699 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311700 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111701 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111702 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11703 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211704 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111705 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611706 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011707 expiration);
[email protected]3912662a32011-10-04 00:51:1111708
bnc691fda62016-08-12 00:43:1611709 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111710 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111711
tfarina42834112016-09-22 13:38:2011712 int rv = trans.Start(&restricted_port_request, callback.callback(),
11713 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111715 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111716 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111717}
11718
bnc55ff9da2015-08-19 18:42:3511719// Ensure that we are not allowed to redirect traffic via an alternate protocol
11720// to an unrestricted (port >= 1024) when the original traffic was on a
11721// restricted port (port < 1024). Ensure that we can redirect in all other
11722// cases.
bncd16676a2016-07-20 16:23:0111723TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111724 HttpRequestInfo unrestricted_port_request;
11725 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511726 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111727 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011728 unrestricted_port_request.traffic_annotation =
11729 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111730
[email protected]d973e99a2012-02-17 21:02:3611731 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111732 StaticSocketDataProvider first_data;
11733 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711734 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111735
11736 MockRead data_reads[] = {
11737 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11738 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611739 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111740 };
11741 StaticSocketDataProvider second_data(
11742 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711743 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511744 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611745 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511746 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111747
danakj1fd259a02016-04-16 03:17:0911748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111749
bnc525e175a2016-06-20 12:36:4011750 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311751 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111752 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111753 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11754 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211755 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111756 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611757 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011758 expiration);
[email protected]3912662a32011-10-04 00:51:1111759
bnc691fda62016-08-12 00:43:1611760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111761 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111762
bnc691fda62016-08-12 00:43:1611763 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011764 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111766 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111767 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111768}
11769
bnc55ff9da2015-08-19 18:42:3511770// Ensure that we are not allowed to redirect traffic via an alternate protocol
11771// to an unrestricted (port >= 1024) when the original traffic was on a
11772// restricted port (port < 1024). Ensure that we can redirect in all other
11773// cases.
bncd16676a2016-07-20 16:23:0111774TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111775 HttpRequestInfo unrestricted_port_request;
11776 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511777 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111778 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011779 unrestricted_port_request.traffic_annotation =
11780 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111781
[email protected]d973e99a2012-02-17 21:02:3611782 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111783 StaticSocketDataProvider first_data;
11784 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711785 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111786
11787 MockRead data_reads[] = {
11788 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11789 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611790 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111791 };
11792 StaticSocketDataProvider second_data(
11793 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711794 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111795
bncb26024382016-06-29 02:39:4511796 SSLSocketDataProvider ssl(ASYNC, OK);
11797 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11798
danakj1fd259a02016-04-16 03:17:0911799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111800
bnc525e175a2016-06-20 12:36:4011801 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311802 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211803 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111804 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11805 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211806 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111807 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611808 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011809 expiration);
[email protected]3912662a32011-10-04 00:51:1111810
bnc691fda62016-08-12 00:43:1611811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111812 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111813
bnc691fda62016-08-12 00:43:1611814 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011815 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111817 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111818 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111819}
11820
bnc55ff9da2015-08-19 18:42:3511821// Ensure that we are not allowed to redirect traffic via an alternate protocol
11822// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11823// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111824TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211825 HttpRequestInfo request;
11826 request.method = "GET";
bncce36dca22015-04-21 22:11:2311827 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011828 request.traffic_annotation =
11829 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211830
11831 // The alternate protocol request will error out before we attempt to connect,
11832 // so only the standard HTTP request will try to connect.
11833 MockRead data_reads[] = {
11834 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11835 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611836 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211837 };
11838 StaticSocketDataProvider data(
11839 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711840 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211841
danakj1fd259a02016-04-16 03:17:0911842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211843
bnc525e175a2016-06-20 12:36:4011844 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211845 session->http_server_properties();
11846 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111847 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11848 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211849 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111850 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611851 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211852
bnc691fda62016-08-12 00:43:1611853 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211854 TestCompletionCallback callback;
11855
tfarina42834112016-09-22 13:38:2011856 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211858 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111859 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211860
bnc691fda62016-08-12 00:43:1611861 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211862 ASSERT_TRUE(response);
11863 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211864 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11865
11866 std::string response_data;
bnc691fda62016-08-12 00:43:1611867 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211868 EXPECT_EQ("hello world", response_data);
11869}
11870
bncd16676a2016-07-20 16:23:0111871TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411872 HttpRequestInfo request;
11873 request.method = "GET";
bncb26024382016-06-29 02:39:4511874 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011875 request.traffic_annotation =
11876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411877
11878 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211879 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311880 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211881 MockRead("\r\n"),
11882 MockRead("hello world"),
11883 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11884 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411885
11886 StaticSocketDataProvider first_transaction(
11887 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711888 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511889 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611890 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411892
bnc032658ba2016-09-26 18:17:1511893 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411894
bncdf80d44fd2016-07-15 20:27:4111895 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511896 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111897 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411898
bnc42331402016-07-25 13:36:1511899 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111900 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411901 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111902 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411903 };
11904
rch8e6c6c42015-05-01 14:05:1311905 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11906 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711907 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411908
[email protected]d973e99a2012-02-17 21:02:3611909 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511910 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11911 NULL, 0, NULL, 0);
11912 hanging_non_alternate_protocol_socket.set_connect_data(
11913 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711914 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511915 &hanging_non_alternate_protocol_socket);
11916
[email protected]49639fa2011-12-20 23:22:4111917 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411918
danakj1fd259a02016-04-16 03:17:0911919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811920 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911921 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411922
tfarina42834112016-09-22 13:38:2011923 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111924 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11925 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411926
11927 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211928 ASSERT_TRUE(response);
11929 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411930 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11931
11932 std::string response_data;
robpercival214763f2016-07-01 23:27:0111933 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411934 EXPECT_EQ("hello world", response_data);
11935
bnc87dcefc2017-05-25 12:47:5811936 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911937 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411938
tfarina42834112016-09-22 13:38:2011939 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11941 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411942
11943 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211944 ASSERT_TRUE(response);
11945 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211946 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311947 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211948 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411949
robpercival214763f2016-07-01 23:27:0111950 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411951 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411952}
11953
bncd16676a2016-07-20 16:23:0111954TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511955 HttpRequestInfo request;
11956 request.method = "GET";
bncb26024382016-06-29 02:39:4511957 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011958 request.traffic_annotation =
11959 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511960
bncb26024382016-06-29 02:39:4511961 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511962 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211963 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311964 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211965 MockRead("\r\n"),
11966 MockRead("hello world"),
11967 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11968 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511969 };
11970
bncb26024382016-06-29 02:39:4511971 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11972 0);
11973 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511974
bncb26024382016-06-29 02:39:4511975 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911976 ssl_http11.ssl_info.cert =
11977 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11978 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511979 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11980
11981 // Second transaction starts an alternative and a non-alternative Job.
11982 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611983 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811984 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11985 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811986 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11987
11988 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11989 hanging_socket2.set_connect_data(never_finishing_connect);
11990 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511991
bncb26024382016-06-29 02:39:4511992 // Third transaction starts an alternative and a non-alternative job.
11993 // The non-alternative job hangs, but the alternative one succeeds.
11994 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111995 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511996 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111997 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511998 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511999 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112000 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512001 };
bnc42331402016-07-25 13:36:1512002 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112003 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512004 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112005 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512006 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112007 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12008 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312009 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512010 };
12011
rch8e6c6c42015-05-01 14:05:1312012 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12013 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712014 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512015
bnc032658ba2016-09-26 18:17:1512016 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512017
mmenkecc2298e2015-12-07 18:20:1812018 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
12019 hanging_socket3.set_connect_data(never_finishing_connect);
12020 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512021
danakj1fd259a02016-04-16 03:17:0912022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112023 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012024 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512025
tfarina42834112016-09-22 13:38:2012026 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12028 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512029
12030 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212031 ASSERT_TRUE(response);
12032 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512033 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12034
12035 std::string response_data;
robpercival214763f2016-07-01 23:27:0112036 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512037 EXPECT_EQ("hello world", response_data);
12038
[email protected]49639fa2011-12-20 23:22:4112039 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012040 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012041 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512043
[email protected]49639fa2011-12-20 23:22:4112044 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012045 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012046 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512048
robpercival214763f2016-07-01 23:27:0112049 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12050 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512051
12052 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212053 ASSERT_TRUE(response);
12054 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212055 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512056 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212057 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112058 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512059 EXPECT_EQ("hello!", response_data);
12060
12061 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212062 ASSERT_TRUE(response);
12063 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212064 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512065 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212066 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112067 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512068 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512069}
12070
bncd16676a2016-07-20 16:23:0112071TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512072 HttpRequestInfo request;
12073 request.method = "GET";
bncb26024382016-06-29 02:39:4512074 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012075 request.traffic_annotation =
12076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512077
12078 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212079 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312080 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212081 MockRead("\r\n"),
12082 MockRead("hello world"),
12083 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12084 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512085 };
12086
12087 StaticSocketDataProvider first_transaction(
12088 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712089 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512090
[email protected]8ddf8322012-02-23 18:08:0612091 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912092 ssl.ssl_info.cert =
12093 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12094 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712095 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512096
[email protected]d973e99a2012-02-17 21:02:3612097 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512098 StaticSocketDataProvider hanging_alternate_protocol_socket(
12099 NULL, 0, NULL, 0);
12100 hanging_alternate_protocol_socket.set_connect_data(
12101 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712102 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512103 &hanging_alternate_protocol_socket);
12104
bncb26024382016-06-29 02:39:4512105 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1812106 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
12107 NULL, 0);
12108 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512109 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512110
[email protected]49639fa2011-12-20 23:22:4112111 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512112
danakj1fd259a02016-04-16 03:17:0912113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812114 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912115 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512116
tfarina42834112016-09-22 13:38:2012117 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12119 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512120
12121 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212122 ASSERT_TRUE(response);
12123 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512124 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12125
12126 std::string response_data;
robpercival214763f2016-07-01 23:27:0112127 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512128 EXPECT_EQ("hello world", response_data);
12129
bnc87dcefc2017-05-25 12:47:5812130 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912131 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512132
tfarina42834112016-09-22 13:38:2012133 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12135 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512136
12137 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212138 ASSERT_TRUE(response);
12139 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512140 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12141 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212142 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512143
robpercival214763f2016-07-01 23:27:0112144 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512145 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512146}
12147
[email protected]631f1322010-04-30 17:59:1112148class CapturingProxyResolver : public ProxyResolver {
12149 public:
Chris Watkins7a41d3552017-12-01 02:13:2712150 CapturingProxyResolver() = default;
12151 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112152
dchengb03027d2014-10-21 12:00:2012153 int GetProxyForURL(const GURL& url,
12154 ProxyInfo* results,
12155 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512156 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012157 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012158 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12159 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212160 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112161 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212162 return OK;
[email protected]631f1322010-04-30 17:59:1112163 }
12164
[email protected]24476402010-07-20 20:55:1712165 const std::vector<GURL>& resolved() const { return resolved_; }
12166
12167 private:
[email protected]631f1322010-04-30 17:59:1112168 std::vector<GURL> resolved_;
12169
12170 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12171};
12172
sammce64b2362015-04-29 03:50:2312173class CapturingProxyResolverFactory : public ProxyResolverFactory {
12174 public:
12175 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12176 : ProxyResolverFactory(false), resolver_(resolver) {}
12177
12178 int CreateProxyResolver(
12179 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0912180 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2312181 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0912182 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912183 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312184 return OK;
12185 }
12186
12187 private:
12188 ProxyResolver* resolver_;
12189};
12190
bnc2e884782016-08-11 19:45:1912191// Test that proxy is resolved using the origin url,
12192// regardless of the alternative server.
12193TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12194 // Configure proxy to bypass www.example.org, which is the origin URL.
12195 ProxyConfig proxy_config;
12196 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12197 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
12198 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1912199 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1912200
12201 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912202 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912203 &capturing_proxy_resolver);
12204
12205 TestNetLog net_log;
12206
Lily Houghton8c2f97d2018-01-22 05:06:5912207 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1912208 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12209 &net_log);
12210
12211 session_deps_.net_log = &net_log;
12212
12213 // Configure alternative service with a hostname that is not bypassed by the
12214 // proxy.
12215 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12216 HttpServerProperties* http_server_properties =
12217 session->http_server_properties();
12218 url::SchemeHostPort server("https", "www.example.org", 443);
12219 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112220 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912221 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112222 http_server_properties->SetHttp2AlternativeService(
12223 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912224
12225 // Non-alternative job should hang.
12226 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
12227 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
12228 nullptr, 0);
12229 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12230 session_deps_.socket_factory->AddSocketDataProvider(
12231 &hanging_alternate_protocol_socket);
12232
bnc032658ba2016-09-26 18:17:1512233 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912234
12235 HttpRequestInfo request;
12236 request.method = "GET";
12237 request.url = GURL("https://www.example.org/");
12238 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012239 request.traffic_annotation =
12240 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912241
12242 SpdySerializedFrame req(
12243 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12244
12245 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12246
12247 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12248 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12249 MockRead spdy_reads[] = {
12250 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12251 };
12252
12253 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12254 arraysize(spdy_writes));
12255 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12256
12257 TestCompletionCallback callback;
12258
12259 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12260
tfarina42834112016-09-22 13:38:2012261 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912262 EXPECT_THAT(callback.GetResult(rv), IsOk());
12263
12264 const HttpResponseInfo* response = trans.GetResponseInfo();
12265 ASSERT_TRUE(response);
12266 ASSERT_TRUE(response->headers);
12267 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12268 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212269 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912270
12271 std::string response_data;
12272 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12273 EXPECT_EQ("hello!", response_data);
12274
12275 // Origin host bypasses proxy, no resolution should have happened.
12276 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12277}
12278
bncd16676a2016-07-20 16:23:0112279TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112280 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212281 proxy_config.set_auto_detect(true);
12282 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112283
sammc5dd160c2015-04-02 02:43:1312284 CapturingProxyResolver capturing_proxy_resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5912285 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1912286 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
12287 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5812288 &capturing_proxy_resolver),
12289 nullptr);
vishal.b62985ca92015-04-17 08:45:5112290 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712291 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112292
12293 HttpRequestInfo request;
12294 request.method = "GET";
bncb26024382016-06-29 02:39:4512295 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012296 request.traffic_annotation =
12297 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112298
12299 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212300 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312301 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212302 MockRead("\r\n"),
12303 MockRead("hello world"),
12304 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12305 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112306 };
12307
12308 StaticSocketDataProvider first_transaction(
12309 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712310 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512311 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612312 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112314
bnc032658ba2016-09-26 18:17:1512315 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112316
bncdf80d44fd2016-07-15 20:27:4112317 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512318 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112319 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312320 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512321 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12322 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312323 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112324 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112325 };
12326
[email protected]d911f1b2010-05-05 22:39:4212327 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12328
bnc42331402016-07-25 13:36:1512329 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112330 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112331 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112332 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12333 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112334 };
12335
rch8e6c6c42015-05-01 14:05:1312336 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12337 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712338 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112339
[email protected]d973e99a2012-02-17 21:02:3612340 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512341 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12342 NULL, 0, NULL, 0);
12343 hanging_non_alternate_protocol_socket.set_connect_data(
12344 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712345 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512346 &hanging_non_alternate_protocol_socket);
12347
[email protected]49639fa2011-12-20 23:22:4112348 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112349
danakj1fd259a02016-04-16 03:17:0912350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812351 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912352 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112353
tfarina42834112016-09-22 13:38:2012354 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12356 EXPECT_THAT(callback.WaitForResult(), IsOk());
12357
12358 const HttpResponseInfo* response = trans->GetResponseInfo();
12359 ASSERT_TRUE(response);
12360 ASSERT_TRUE(response->headers);
12361 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12362 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212363 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112364
12365 std::string response_data;
12366 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12367 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112368
bnc87dcefc2017-05-25 12:47:5812369 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912370 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112371
tfarina42834112016-09-22 13:38:2012372 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12374 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112375
mmenkea2dcd3bf2016-08-16 21:49:4112376 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212377 ASSERT_TRUE(response);
12378 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212379 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312380 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212381 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112382
robpercival214763f2016-07-01 23:27:0112383 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112384 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512385 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12386 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312387 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312388 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312389 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112390
[email protected]029c83b62013-01-24 05:28:2012391 LoadTimingInfo load_timing_info;
12392 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12393 TestLoadTimingNotReusedWithPac(load_timing_info,
12394 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112395}
[email protected]631f1322010-04-30 17:59:1112396
bncd16676a2016-07-20 16:23:0112397TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812398 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412399 HttpRequestInfo request;
12400 request.method = "GET";
bncb26024382016-06-29 02:39:4512401 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012402 request.traffic_annotation =
12403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412404
12405 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212406 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312407 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212408 MockRead("\r\n"),
12409 MockRead("hello world"),
12410 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412411 };
12412
12413 StaticSocketDataProvider first_transaction(
12414 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712415 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512416 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612417 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412419
bnc032658ba2016-09-26 18:17:1512420 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412421
bncdf80d44fd2016-07-15 20:27:4112422 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512423 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112424 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412425
bnc42331402016-07-25 13:36:1512426 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112427 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412428 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112429 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412430 };
12431
rch8e6c6c42015-05-01 14:05:1312432 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12433 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712434 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412435
[email protected]83039bb2011-12-09 18:43:5512436 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412437
danakj1fd259a02016-04-16 03:17:0912438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412439
bnc87dcefc2017-05-25 12:47:5812440 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912441 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412442
tfarina42834112016-09-22 13:38:2012443 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12445 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412446
12447 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212448 ASSERT_TRUE(response);
12449 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412450 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12451
12452 std::string response_data;
robpercival214763f2016-07-01 23:27:0112453 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412454 EXPECT_EQ("hello world", response_data);
12455
12456 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512457 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012458 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412459 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712460 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212461 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812462
bnc87dcefc2017-05-25 12:47:5812463 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912464 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412465
tfarina42834112016-09-22 13:38:2012466 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12468 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412469
12470 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212471 ASSERT_TRUE(response);
12472 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212473 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312474 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212475 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412476
robpercival214763f2016-07-01 23:27:0112477 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412478 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212479}
12480
[email protected]044de0642010-06-17 10:42:1512481// GenerateAuthToken is a mighty big test.
12482// It tests all permutation of GenerateAuthToken behavior:
12483// - Synchronous and Asynchronous completion.
12484// - OK or error on completion.
12485// - Direct connection, non-authenticating proxy, and authenticating proxy.
12486// - HTTP or HTTPS backend (to include proxy tunneling).
12487// - Non-authenticating and authenticating backend.
12488//
[email protected]fe3b7dc2012-02-03 19:52:0912489// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512490// problems generating an auth token for an authenticating proxy, we don't
12491// need to test all permutations of the backend server).
12492//
12493// The test proceeds by going over each of the configuration cases, and
12494// potentially running up to three rounds in each of the tests. The TestConfig
12495// specifies both the configuration for the test as well as the expectations
12496// for the results.
bncd16676a2016-07-20 16:23:0112497TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012498 static const char kServer[] = "http://www.example.com";
12499 static const char kSecureServer[] = "https://www.example.com";
12500 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512501
12502 enum AuthTiming {
12503 AUTH_NONE,
12504 AUTH_SYNC,
12505 AUTH_ASYNC,
12506 };
12507
12508 const MockWrite kGet(
12509 "GET / HTTP/1.1\r\n"
12510 "Host: www.example.com\r\n"
12511 "Connection: keep-alive\r\n\r\n");
12512 const MockWrite kGetProxy(
12513 "GET http://www.example.com/ HTTP/1.1\r\n"
12514 "Host: www.example.com\r\n"
12515 "Proxy-Connection: keep-alive\r\n\r\n");
12516 const MockWrite kGetAuth(
12517 "GET / HTTP/1.1\r\n"
12518 "Host: www.example.com\r\n"
12519 "Connection: keep-alive\r\n"
12520 "Authorization: auth_token\r\n\r\n");
12521 const MockWrite kGetProxyAuth(
12522 "GET http://www.example.com/ HTTP/1.1\r\n"
12523 "Host: www.example.com\r\n"
12524 "Proxy-Connection: keep-alive\r\n"
12525 "Proxy-Authorization: auth_token\r\n\r\n");
12526 const MockWrite kGetAuthThroughProxy(
12527 "GET http://www.example.com/ HTTP/1.1\r\n"
12528 "Host: www.example.com\r\n"
12529 "Proxy-Connection: keep-alive\r\n"
12530 "Authorization: auth_token\r\n\r\n");
12531 const MockWrite kGetAuthWithProxyAuth(
12532 "GET http://www.example.com/ HTTP/1.1\r\n"
12533 "Host: www.example.com\r\n"
12534 "Proxy-Connection: keep-alive\r\n"
12535 "Proxy-Authorization: auth_token\r\n"
12536 "Authorization: auth_token\r\n\r\n");
12537 const MockWrite kConnect(
12538 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712539 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512540 "Proxy-Connection: keep-alive\r\n\r\n");
12541 const MockWrite kConnectProxyAuth(
12542 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712543 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512544 "Proxy-Connection: keep-alive\r\n"
12545 "Proxy-Authorization: auth_token\r\n\r\n");
12546
12547 const MockRead kSuccess(
12548 "HTTP/1.1 200 OK\r\n"
12549 "Content-Type: text/html; charset=iso-8859-1\r\n"
12550 "Content-Length: 3\r\n\r\n"
12551 "Yes");
12552 const MockRead kFailure(
12553 "Should not be called.");
12554 const MockRead kServerChallenge(
12555 "HTTP/1.1 401 Unauthorized\r\n"
12556 "WWW-Authenticate: Mock realm=server\r\n"
12557 "Content-Type: text/html; charset=iso-8859-1\r\n"
12558 "Content-Length: 14\r\n\r\n"
12559 "Unauthorized\r\n");
12560 const MockRead kProxyChallenge(
12561 "HTTP/1.1 407 Unauthorized\r\n"
12562 "Proxy-Authenticate: Mock realm=proxy\r\n"
12563 "Proxy-Connection: close\r\n"
12564 "Content-Type: text/html; charset=iso-8859-1\r\n"
12565 "Content-Length: 14\r\n\r\n"
12566 "Unauthorized\r\n");
12567 const MockRead kProxyConnected(
12568 "HTTP/1.1 200 Connection Established\r\n\r\n");
12569
12570 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12571 // no constructors, but the C++ compiler on Windows warns about
12572 // unspecified data in compound literals. So, moved to using constructors,
12573 // and TestRound's created with the default constructor should not be used.
12574 struct TestRound {
12575 TestRound()
12576 : expected_rv(ERR_UNEXPECTED),
12577 extra_write(NULL),
12578 extra_read(NULL) {
12579 }
12580 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12581 int expected_rv_arg)
12582 : write(write_arg),
12583 read(read_arg),
12584 expected_rv(expected_rv_arg),
12585 extra_write(NULL),
12586 extra_read(NULL) {
12587 }
12588 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12589 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112590 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512591 : write(write_arg),
12592 read(read_arg),
12593 expected_rv(expected_rv_arg),
12594 extra_write(extra_write_arg),
12595 extra_read(extra_read_arg) {
12596 }
12597 MockWrite write;
12598 MockRead read;
12599 int expected_rv;
12600 const MockWrite* extra_write;
12601 const MockRead* extra_read;
12602 };
12603
12604 static const int kNoSSL = 500;
12605
12606 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112607 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112608 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512609 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112610 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112611 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512612 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112613 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512614 int num_auth_rounds;
12615 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612616 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512617 } test_configs[] = {
asankac93076192016-10-03 15:46:0212618 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112619 {__LINE__,
12620 nullptr,
asankac93076192016-10-03 15:46:0212621 AUTH_NONE,
12622 OK,
12623 kServer,
12624 AUTH_NONE,
12625 OK,
12626 1,
12627 kNoSSL,
12628 {TestRound(kGet, kSuccess, OK)}},
12629 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112630 {__LINE__,
12631 nullptr,
asankac93076192016-10-03 15:46:0212632 AUTH_NONE,
12633 OK,
12634 kServer,
12635 AUTH_SYNC,
12636 OK,
12637 2,
12638 kNoSSL,
12639 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512640 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112641 {__LINE__,
12642 nullptr,
asankac93076192016-10-03 15:46:0212643 AUTH_NONE,
12644 OK,
12645 kServer,
12646 AUTH_SYNC,
12647 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612648 3,
12649 kNoSSL,
12650 {TestRound(kGet, kServerChallenge, OK),
12651 TestRound(kGet, kServerChallenge, OK),
12652 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112653 {__LINE__,
12654 nullptr,
asankae2257db2016-10-11 22:03:1612655 AUTH_NONE,
12656 OK,
12657 kServer,
12658 AUTH_SYNC,
12659 ERR_UNSUPPORTED_AUTH_SCHEME,
12660 2,
12661 kNoSSL,
12662 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112663 {__LINE__,
12664 nullptr,
asankae2257db2016-10-11 22:03:1612665 AUTH_NONE,
12666 OK,
12667 kServer,
12668 AUTH_SYNC,
12669 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12670 2,
12671 kNoSSL,
12672 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112673 {__LINE__,
12674 kProxy,
asankae2257db2016-10-11 22:03:1612675 AUTH_SYNC,
12676 ERR_FAILED,
12677 kServer,
12678 AUTH_NONE,
12679 OK,
12680 2,
12681 kNoSSL,
12682 {TestRound(kGetProxy, kProxyChallenge, OK),
12683 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112684 {__LINE__,
12685 kProxy,
asankae2257db2016-10-11 22:03:1612686 AUTH_ASYNC,
12687 ERR_FAILED,
12688 kServer,
12689 AUTH_NONE,
12690 OK,
12691 2,
12692 kNoSSL,
12693 {TestRound(kGetProxy, kProxyChallenge, OK),
12694 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112695 {__LINE__,
12696 nullptr,
asankae2257db2016-10-11 22:03:1612697 AUTH_NONE,
12698 OK,
12699 kServer,
12700 AUTH_SYNC,
12701 ERR_FAILED,
asankac93076192016-10-03 15:46:0212702 2,
12703 kNoSSL,
12704 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612705 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112706 {__LINE__,
12707 nullptr,
asankae2257db2016-10-11 22:03:1612708 AUTH_NONE,
12709 OK,
12710 kServer,
12711 AUTH_ASYNC,
12712 ERR_FAILED,
12713 2,
12714 kNoSSL,
12715 {TestRound(kGet, kServerChallenge, OK),
12716 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112717 {__LINE__,
12718 nullptr,
asankac93076192016-10-03 15:46:0212719 AUTH_NONE,
12720 OK,
12721 kServer,
12722 AUTH_ASYNC,
12723 OK,
12724 2,
12725 kNoSSL,
12726 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512727 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112728 {__LINE__,
12729 nullptr,
asankac93076192016-10-03 15:46:0212730 AUTH_NONE,
12731 OK,
12732 kServer,
12733 AUTH_ASYNC,
12734 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612735 3,
asankac93076192016-10-03 15:46:0212736 kNoSSL,
12737 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612738 // The second round uses a HttpAuthHandlerMock that always succeeds.
12739 TestRound(kGet, kServerChallenge, OK),
12740 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212741 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112742 {__LINE__,
12743 kProxy,
asankac93076192016-10-03 15:46:0212744 AUTH_NONE,
12745 OK,
12746 kServer,
12747 AUTH_NONE,
12748 OK,
12749 1,
12750 kNoSSL,
12751 {TestRound(kGetProxy, kSuccess, OK)}},
12752 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112753 {__LINE__,
12754 kProxy,
asankac93076192016-10-03 15:46:0212755 AUTH_NONE,
12756 OK,
12757 kServer,
12758 AUTH_SYNC,
12759 OK,
12760 2,
12761 kNoSSL,
12762 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512763 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112764 {__LINE__,
12765 kProxy,
asankac93076192016-10-03 15:46:0212766 AUTH_NONE,
12767 OK,
12768 kServer,
12769 AUTH_SYNC,
12770 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612771 3,
asankac93076192016-10-03 15:46:0212772 kNoSSL,
12773 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612774 TestRound(kGetProxy, kServerChallenge, OK),
12775 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112776 {__LINE__,
12777 kProxy,
asankac93076192016-10-03 15:46:0212778 AUTH_NONE,
12779 OK,
12780 kServer,
12781 AUTH_ASYNC,
12782 OK,
12783 2,
12784 kNoSSL,
12785 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512786 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112787 {__LINE__,
12788 kProxy,
asankac93076192016-10-03 15:46:0212789 AUTH_NONE,
12790 OK,
12791 kServer,
12792 AUTH_ASYNC,
12793 ERR_INVALID_AUTH_CREDENTIALS,
12794 2,
12795 kNoSSL,
12796 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612797 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212798 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112799 {__LINE__,
12800 kProxy,
asankac93076192016-10-03 15:46:0212801 AUTH_SYNC,
12802 OK,
12803 kServer,
12804 AUTH_NONE,
12805 OK,
12806 2,
12807 kNoSSL,
12808 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512809 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112810 {__LINE__,
12811 kProxy,
asankac93076192016-10-03 15:46:0212812 AUTH_SYNC,
12813 ERR_INVALID_AUTH_CREDENTIALS,
12814 kServer,
12815 AUTH_NONE,
12816 OK,
12817 2,
12818 kNoSSL,
12819 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612820 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112821 {__LINE__,
12822 kProxy,
asankac93076192016-10-03 15:46:0212823 AUTH_ASYNC,
12824 OK,
12825 kServer,
12826 AUTH_NONE,
12827 OK,
12828 2,
12829 kNoSSL,
12830 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512831 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112832 {__LINE__,
12833 kProxy,
asankac93076192016-10-03 15:46:0212834 AUTH_ASYNC,
12835 ERR_INVALID_AUTH_CREDENTIALS,
12836 kServer,
12837 AUTH_NONE,
12838 OK,
12839 2,
12840 kNoSSL,
12841 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612842 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112843 {__LINE__,
12844 kProxy,
12845 AUTH_ASYNC,
12846 ERR_INVALID_AUTH_CREDENTIALS,
12847 kServer,
12848 AUTH_NONE,
12849 OK,
12850 3,
12851 kNoSSL,
12852 {TestRound(kGetProxy, kProxyChallenge, OK),
12853 TestRound(kGetProxy, kProxyChallenge, OK),
12854 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212855 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112856 {__LINE__,
12857 kProxy,
asankac93076192016-10-03 15:46:0212858 AUTH_SYNC,
12859 OK,
12860 kServer,
12861 AUTH_SYNC,
12862 OK,
12863 3,
12864 kNoSSL,
12865 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512866 TestRound(kGetProxyAuth, kServerChallenge, OK),
12867 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112868 {__LINE__,
12869 kProxy,
asankac93076192016-10-03 15:46:0212870 AUTH_SYNC,
12871 OK,
12872 kServer,
12873 AUTH_SYNC,
12874 ERR_INVALID_AUTH_CREDENTIALS,
12875 3,
12876 kNoSSL,
12877 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512878 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612879 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112880 {__LINE__,
12881 kProxy,
asankac93076192016-10-03 15:46:0212882 AUTH_ASYNC,
12883 OK,
12884 kServer,
12885 AUTH_SYNC,
12886 OK,
12887 3,
12888 kNoSSL,
12889 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512890 TestRound(kGetProxyAuth, kServerChallenge, OK),
12891 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112892 {__LINE__,
12893 kProxy,
asankac93076192016-10-03 15:46:0212894 AUTH_ASYNC,
12895 OK,
12896 kServer,
12897 AUTH_SYNC,
12898 ERR_INVALID_AUTH_CREDENTIALS,
12899 3,
12900 kNoSSL,
12901 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512902 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612903 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112904 {__LINE__,
12905 kProxy,
asankac93076192016-10-03 15:46:0212906 AUTH_SYNC,
12907 OK,
12908 kServer,
12909 AUTH_ASYNC,
12910 OK,
12911 3,
12912 kNoSSL,
12913 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512914 TestRound(kGetProxyAuth, kServerChallenge, OK),
12915 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112916 {__LINE__,
12917 kProxy,
12918 AUTH_SYNC,
12919 ERR_INVALID_AUTH_CREDENTIALS,
12920 kServer,
12921 AUTH_ASYNC,
12922 OK,
12923 4,
12924 kNoSSL,
12925 {TestRound(kGetProxy, kProxyChallenge, OK),
12926 TestRound(kGetProxy, kProxyChallenge, OK),
12927 TestRound(kGetProxyAuth, kServerChallenge, OK),
12928 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12929 {__LINE__,
12930 kProxy,
asankac93076192016-10-03 15:46:0212931 AUTH_SYNC,
12932 OK,
12933 kServer,
12934 AUTH_ASYNC,
12935 ERR_INVALID_AUTH_CREDENTIALS,
12936 3,
12937 kNoSSL,
12938 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512939 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612940 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112941 {__LINE__,
12942 kProxy,
asankac93076192016-10-03 15:46:0212943 AUTH_ASYNC,
12944 OK,
12945 kServer,
12946 AUTH_ASYNC,
12947 OK,
12948 3,
12949 kNoSSL,
12950 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512951 TestRound(kGetProxyAuth, kServerChallenge, OK),
12952 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112953 {__LINE__,
12954 kProxy,
asankac93076192016-10-03 15:46:0212955 AUTH_ASYNC,
12956 OK,
12957 kServer,
12958 AUTH_ASYNC,
12959 ERR_INVALID_AUTH_CREDENTIALS,
12960 3,
12961 kNoSSL,
12962 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512963 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612964 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112965 {__LINE__,
12966 kProxy,
12967 AUTH_ASYNC,
12968 ERR_INVALID_AUTH_CREDENTIALS,
12969 kServer,
12970 AUTH_ASYNC,
12971 ERR_INVALID_AUTH_CREDENTIALS,
12972 4,
12973 kNoSSL,
12974 {TestRound(kGetProxy, kProxyChallenge, OK),
12975 TestRound(kGetProxy, kProxyChallenge, OK),
12976 TestRound(kGetProxyAuth, kServerChallenge, OK),
12977 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212978 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112979 {__LINE__,
12980 nullptr,
asankac93076192016-10-03 15:46:0212981 AUTH_NONE,
12982 OK,
12983 kSecureServer,
12984 AUTH_NONE,
12985 OK,
12986 1,
12987 0,
12988 {TestRound(kGet, kSuccess, OK)}},
12989 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112990 {__LINE__,
12991 nullptr,
asankac93076192016-10-03 15:46:0212992 AUTH_NONE,
12993 OK,
12994 kSecureServer,
12995 AUTH_SYNC,
12996 OK,
12997 2,
12998 0,
12999 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513000 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113001 {__LINE__,
13002 nullptr,
asankac93076192016-10-03 15:46:0213003 AUTH_NONE,
13004 OK,
13005 kSecureServer,
13006 AUTH_SYNC,
13007 ERR_INVALID_AUTH_CREDENTIALS,
13008 2,
13009 0,
asankae2257db2016-10-11 22:03:1613010 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113011 {__LINE__,
13012 nullptr,
asankac93076192016-10-03 15:46:0213013 AUTH_NONE,
13014 OK,
13015 kSecureServer,
13016 AUTH_ASYNC,
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_ASYNC,
13028 ERR_INVALID_AUTH_CREDENTIALS,
13029 2,
13030 0,
asankae2257db2016-10-11 22:03:1613031 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213032 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113033 {__LINE__,
13034 kProxy,
asankac93076192016-10-03 15:46:0213035 AUTH_NONE,
13036 OK,
13037 kSecureServer,
13038 AUTH_NONE,
13039 OK,
13040 1,
13041 0,
13042 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13043 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113044 {__LINE__,
13045 kProxy,
asankac93076192016-10-03 15:46:0213046 AUTH_NONE,
13047 OK,
13048 kSecureServer,
13049 AUTH_SYNC,
13050 OK,
13051 2,
13052 0,
13053 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513054 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113055 {__LINE__,
13056 kProxy,
asankac93076192016-10-03 15:46:0213057 AUTH_NONE,
13058 OK,
13059 kSecureServer,
13060 AUTH_SYNC,
13061 ERR_INVALID_AUTH_CREDENTIALS,
13062 2,
13063 0,
13064 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613065 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113066 {__LINE__,
13067 kProxy,
asankac93076192016-10-03 15:46:0213068 AUTH_NONE,
13069 OK,
13070 kSecureServer,
13071 AUTH_ASYNC,
13072 OK,
13073 2,
13074 0,
13075 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513076 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113077 {__LINE__,
13078 kProxy,
asankac93076192016-10-03 15:46:0213079 AUTH_NONE,
13080 OK,
13081 kSecureServer,
13082 AUTH_ASYNC,
13083 ERR_INVALID_AUTH_CREDENTIALS,
13084 2,
13085 0,
13086 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613087 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213088 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113089 {__LINE__,
13090 kProxy,
asankac93076192016-10-03 15:46:0213091 AUTH_SYNC,
13092 OK,
13093 kSecureServer,
13094 AUTH_NONE,
13095 OK,
13096 2,
13097 1,
13098 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513099 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113100 {__LINE__,
13101 kProxy,
asankac93076192016-10-03 15:46:0213102 AUTH_SYNC,
13103 ERR_INVALID_AUTH_CREDENTIALS,
13104 kSecureServer,
13105 AUTH_NONE,
13106 OK,
13107 2,
13108 kNoSSL,
13109 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613110 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113111 {__LINE__,
13112 kProxy,
asankae2257db2016-10-11 22:03:1613113 AUTH_SYNC,
13114 ERR_UNSUPPORTED_AUTH_SCHEME,
13115 kSecureServer,
13116 AUTH_NONE,
13117 OK,
13118 2,
13119 kNoSSL,
13120 {TestRound(kConnect, kProxyChallenge, OK),
13121 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113122 {__LINE__,
13123 kProxy,
asankae2257db2016-10-11 22:03:1613124 AUTH_SYNC,
13125 ERR_UNEXPECTED,
13126 kSecureServer,
13127 AUTH_NONE,
13128 OK,
13129 2,
13130 kNoSSL,
13131 {TestRound(kConnect, kProxyChallenge, OK),
13132 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113133 {__LINE__,
13134 kProxy,
asankac93076192016-10-03 15:46:0213135 AUTH_ASYNC,
13136 OK,
13137 kSecureServer,
13138 AUTH_NONE,
13139 OK,
13140 2,
13141 1,
13142 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513143 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113144 {__LINE__,
13145 kProxy,
asankac93076192016-10-03 15:46:0213146 AUTH_ASYNC,
13147 ERR_INVALID_AUTH_CREDENTIALS,
13148 kSecureServer,
13149 AUTH_NONE,
13150 OK,
13151 2,
13152 kNoSSL,
13153 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613154 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213155 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113156 {__LINE__,
13157 kProxy,
asankac93076192016-10-03 15:46:0213158 AUTH_SYNC,
13159 OK,
13160 kSecureServer,
13161 AUTH_SYNC,
13162 OK,
13163 3,
13164 1,
13165 {TestRound(kConnect, kProxyChallenge, OK),
13166 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13167 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513168 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113169 {__LINE__,
13170 kProxy,
asankac93076192016-10-03 15:46:0213171 AUTH_SYNC,
13172 OK,
13173 kSecureServer,
13174 AUTH_SYNC,
13175 ERR_INVALID_AUTH_CREDENTIALS,
13176 3,
13177 1,
13178 {TestRound(kConnect, kProxyChallenge, OK),
13179 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13180 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613181 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113182 {__LINE__,
13183 kProxy,
asankac93076192016-10-03 15:46:0213184 AUTH_ASYNC,
13185 OK,
13186 kSecureServer,
13187 AUTH_SYNC,
13188 OK,
13189 3,
13190 1,
13191 {TestRound(kConnect, kProxyChallenge, OK),
13192 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13193 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513194 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113195 {__LINE__,
13196 kProxy,
asankac93076192016-10-03 15:46:0213197 AUTH_ASYNC,
13198 OK,
13199 kSecureServer,
13200 AUTH_SYNC,
13201 ERR_INVALID_AUTH_CREDENTIALS,
13202 3,
13203 1,
13204 {TestRound(kConnect, kProxyChallenge, OK),
13205 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13206 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613207 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113208 {__LINE__,
13209 kProxy,
asankac93076192016-10-03 15:46:0213210 AUTH_SYNC,
13211 OK,
13212 kSecureServer,
13213 AUTH_ASYNC,
13214 OK,
13215 3,
13216 1,
13217 {TestRound(kConnect, kProxyChallenge, OK),
13218 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13219 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513220 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113221 {__LINE__,
13222 kProxy,
asankac93076192016-10-03 15:46:0213223 AUTH_SYNC,
13224 OK,
13225 kSecureServer,
13226 AUTH_ASYNC,
13227 ERR_INVALID_AUTH_CREDENTIALS,
13228 3,
13229 1,
13230 {TestRound(kConnect, kProxyChallenge, OK),
13231 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13232 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613233 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113234 {__LINE__,
13235 kProxy,
asankac93076192016-10-03 15:46:0213236 AUTH_ASYNC,
13237 OK,
13238 kSecureServer,
13239 AUTH_ASYNC,
13240 OK,
13241 3,
13242 1,
13243 {TestRound(kConnect, kProxyChallenge, OK),
13244 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13245 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513246 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113247 {__LINE__,
13248 kProxy,
asankac93076192016-10-03 15:46:0213249 AUTH_ASYNC,
13250 OK,
13251 kSecureServer,
13252 AUTH_ASYNC,
13253 ERR_INVALID_AUTH_CREDENTIALS,
13254 3,
13255 1,
13256 {TestRound(kConnect, kProxyChallenge, OK),
13257 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13258 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613259 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113260 {__LINE__,
13261 kProxy,
13262 AUTH_ASYNC,
13263 ERR_INVALID_AUTH_CREDENTIALS,
13264 kSecureServer,
13265 AUTH_ASYNC,
13266 ERR_INVALID_AUTH_CREDENTIALS,
13267 4,
13268 2,
13269 {TestRound(kConnect, kProxyChallenge, OK),
13270 TestRound(kConnect, kProxyChallenge, OK),
13271 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13272 &kServerChallenge),
13273 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513274 };
13275
asanka463ca4262016-11-16 02:34:3113276 for (const auto& test_config : test_configs) {
13277 SCOPED_TRACE(::testing::Message() << "Test config at "
13278 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813279 HttpAuthHandlerMock::Factory* auth_factory(
13280 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713281 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913282 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613283
13284 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513285 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113286 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813287 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13288 std::string auth_challenge = "Mock realm=proxy";
13289 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413290 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13291 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813292 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013293 empty_ssl_info, origin,
13294 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813295 auth_handler->SetGenerateExpectation(
13296 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113297 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813298 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13299 }
[email protected]044de0642010-06-17 10:42:1513300 }
13301 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013302 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513303 std::string auth_challenge = "Mock realm=server";
13304 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413305 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13306 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513307 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013308 empty_ssl_info, origin,
13309 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513310 auth_handler->SetGenerateExpectation(
13311 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113312 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813313 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613314
13315 // The second handler always succeeds. It should only be used where there
13316 // are multiple auth sessions for server auth in the same network
13317 // transaction using the same auth scheme.
13318 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913319 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613320 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13321 empty_ssl_info, origin,
13322 NetLogWithSource());
13323 second_handler->SetGenerateExpectation(true, OK);
13324 auth_factory->AddMockHandler(second_handler.release(),
13325 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513326 }
13327 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913328 session_deps_.proxy_resolution_service =
13329 ProxyResolutionService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1513330 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913331 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513332 }
13333
13334 HttpRequestInfo request;
13335 request.method = "GET";
13336 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1013337 request.traffic_annotation =
13338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513339
danakj1fd259a02016-04-16 03:17:0913340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513341
rchcb68dc62015-05-21 04:45:3613342 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13343
13344 std::vector<std::vector<MockRead>> mock_reads(1);
13345 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513346 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213347 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513348 const TestRound& read_write_round = test_config.rounds[round];
13349
13350 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613351 mock_reads.back().push_back(read_write_round.read);
13352 mock_writes.back().push_back(read_write_round.write);
13353
13354 // kProxyChallenge uses Proxy-Connection: close which means that the
13355 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413356 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613357 mock_reads.push_back(std::vector<MockRead>());
13358 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513359 }
13360
rchcb68dc62015-05-21 04:45:3613361 if (read_write_round.extra_read) {
13362 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513363 }
rchcb68dc62015-05-21 04:45:3613364 if (read_write_round.extra_write) {
13365 mock_writes.back().push_back(*read_write_round.extra_write);
13366 }
[email protected]044de0642010-06-17 10:42:1513367
13368 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513369 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713370 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513371 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613372 }
[email protected]044de0642010-06-17 10:42:1513373
danakj1fd259a02016-04-16 03:17:0913374 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613375 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913376 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413377 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813378 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613379 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213380 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613381 }
13382
mmenkecc2298e2015-12-07 18:20:1813383 // Transaction must be created after DataProviders, so it's destroyed before
13384 // they are as well.
13385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13386
rchcb68dc62015-05-21 04:45:3613387 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213388 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613389 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513390 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113391 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513392 int rv;
13393 if (round == 0) {
tfarina42834112016-09-22 13:38:2013394 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513395 } else {
[email protected]49639fa2011-12-20 23:22:4113396 rv = trans.RestartWithAuth(
13397 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513398 }
13399 if (rv == ERR_IO_PENDING)
13400 rv = callback.WaitForResult();
13401
13402 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613403 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013404 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513405 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513406 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13407 continue;
13408 }
13409 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213410 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513411 } else {
wezca1070932016-05-26 20:30:5213412 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613413 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513414 }
13415 }
[email protected]e5ae96a2010-04-14 20:12:4513416 }
13417}
13418
bncd16676a2016-07-20 16:23:0113419TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413420 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413421 HttpAuthHandlerMock::Factory* auth_factory(
13422 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713423 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913424 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713425 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13426 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413427
13428 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13429 auth_handler->set_connection_based(true);
13430 std::string auth_challenge = "Mock realm=server";
13431 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413432 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13433 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913434 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413435 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013436 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813437 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413438
[email protected]c871bce92010-07-15 21:51:1413439 int rv = OK;
13440 const HttpResponseInfo* response = NULL;
13441 HttpRequestInfo request;
13442 request.method = "GET";
13443 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1013444 request.traffic_annotation =
13445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713446
danakj1fd259a02016-04-16 03:17:0913447 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013448
13449 // Use a TCP Socket Pool with only one connection per group. This is used
13450 // to validate that the TCP socket is not released to the pool between
13451 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213452 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813453 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013454 50, // Max sockets for pool
13455 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113456 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13457 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913458 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213459 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813460 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013461
bnc691fda62016-08-12 00:43:1613462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113463 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413464
13465 const MockWrite kGet(
13466 "GET / HTTP/1.1\r\n"
13467 "Host: www.example.com\r\n"
13468 "Connection: keep-alive\r\n\r\n");
13469 const MockWrite kGetAuth(
13470 "GET / HTTP/1.1\r\n"
13471 "Host: www.example.com\r\n"
13472 "Connection: keep-alive\r\n"
13473 "Authorization: auth_token\r\n\r\n");
13474
13475 const MockRead kServerChallenge(
13476 "HTTP/1.1 401 Unauthorized\r\n"
13477 "WWW-Authenticate: Mock realm=server\r\n"
13478 "Content-Type: text/html; charset=iso-8859-1\r\n"
13479 "Content-Length: 14\r\n\r\n"
13480 "Unauthorized\r\n");
13481 const MockRead kSuccess(
13482 "HTTP/1.1 200 OK\r\n"
13483 "Content-Type: text/html; charset=iso-8859-1\r\n"
13484 "Content-Length: 3\r\n\r\n"
13485 "Yes");
13486
13487 MockWrite writes[] = {
13488 // First round
13489 kGet,
13490 // Second round
13491 kGetAuth,
13492 // Third round
13493 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013494 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013495 kGetAuth,
13496 // Competing request
13497 kGet,
[email protected]c871bce92010-07-15 21:51:1413498 };
13499 MockRead reads[] = {
13500 // First round
13501 kServerChallenge,
13502 // Second round
13503 kServerChallenge,
13504 // Third round
[email protected]eca50e122010-09-11 14:03:3013505 kServerChallenge,
13506 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413507 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013508 // Competing response
13509 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413510 };
13511 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13512 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713513 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413514
thestig9d3bb0c2015-01-24 00:49:5113515 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013516
13517 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413518 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013519 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413520 if (rv == ERR_IO_PENDING)
13521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113522 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613523 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213524 ASSERT_TRUE(response);
13525 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813526 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113527 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13528 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413529
[email protected]7ef4cbbb2011-02-06 11:19:1013530 // In between rounds, another request comes in for the same domain.
13531 // It should not be able to grab the TCP socket that trans has already
13532 // claimed.
bnc691fda62016-08-12 00:43:1613533 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113534 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013535 rv = trans_compete.Start(&request, callback_compete.callback(),
13536 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013538 // callback_compete.WaitForResult at this point would stall forever,
13539 // since the HttpNetworkTransaction does not release the request back to
13540 // the pool until after authentication completes.
13541
13542 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413543 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613544 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413545 if (rv == ERR_IO_PENDING)
13546 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113547 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613548 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213549 ASSERT_TRUE(response);
13550 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813551 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113552 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13553 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413554
[email protected]7ef4cbbb2011-02-06 11:19:1013555 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413556 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613557 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413558 if (rv == ERR_IO_PENDING)
13559 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113560 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613561 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213562 ASSERT_TRUE(response);
13563 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813564 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113565 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13566 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013567
[email protected]7ef4cbbb2011-02-06 11:19:1013568 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013569 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613570 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013571 if (rv == ERR_IO_PENDING)
13572 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113573 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613574 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213575 ASSERT_TRUE(response);
13576 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813577 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013578
asanka463ca4262016-11-16 02:34:3113579 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13580 // auth handler should transition to a DONE state in concert with the remote
13581 // server. But that's not something we can test here with a mock handler.
13582 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13583 auth_handler->state());
13584
[email protected]7ef4cbbb2011-02-06 11:19:1013585 // Read the body since the fourth round was successful. This will also
13586 // release the socket back to the pool.
13587 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613588 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013589 if (rv == ERR_IO_PENDING)
13590 rv = callback.WaitForResult();
13591 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613592 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013593 EXPECT_EQ(0, rv);
13594 // There are still 0 idle sockets, since the trans_compete transaction
13595 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813596 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013597
13598 // The competing request can now finish. Wait for the headers and then
13599 // read the body.
13600 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113601 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613602 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013603 if (rv == ERR_IO_PENDING)
13604 rv = callback.WaitForResult();
13605 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613606 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013607 EXPECT_EQ(0, rv);
13608
13609 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813610 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413611}
13612
[email protected]65041fa2010-05-21 06:56:5313613// This tests the case that a request is issued via http instead of spdy after
13614// npn is negotiated.
bncd16676a2016-07-20 16:23:0113615TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313616 HttpRequestInfo request;
13617 request.method = "GET";
bncce36dca22015-04-21 22:11:2313618 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013619 request.traffic_annotation =
13620 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313621
13622 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313623 MockWrite(
13624 "GET / HTTP/1.1\r\n"
13625 "Host: www.example.org\r\n"
13626 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313627 };
13628
13629 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213630 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313631 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213632 MockRead("\r\n"),
13633 MockRead("hello world"),
13634 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313635 };
13636
[email protected]8ddf8322012-02-23 18:08:0613637 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613638 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313639
[email protected]bb88e1d32013-05-03 23:11:0713640 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313641
13642 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13643 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713644 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313645
[email protected]49639fa2011-12-20 23:22:4113646 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313647
danakj1fd259a02016-04-16 03:17:0913648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313650
tfarina42834112016-09-22 13:38:2013651 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313652
robpercival214763f2016-07-01 23:27:0113653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13654 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313655
bnc691fda62016-08-12 00:43:1613656 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213657 ASSERT_TRUE(response);
13658 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313659 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13660
13661 std::string response_data;
bnc691fda62016-08-12 00:43:1613662 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313663 EXPECT_EQ("hello world", response_data);
13664
13665 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213666 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313667}
[email protected]26ef6582010-06-24 02:30:4713668
bnc55ff9da2015-08-19 18:42:3513669// Simulate the SSL handshake completing with an NPN negotiation followed by an
13670// immediate server closing of the socket.
13671// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113672TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713673 HttpRequestInfo request;
13674 request.method = "GET";
bncce36dca22015-04-21 22:11:2313675 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013676 request.traffic_annotation =
13677 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713678
[email protected]8ddf8322012-02-23 18:08:0613679 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613680 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713682
Bence Béky27ad0a12018-02-08 00:35:4813683 SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113684 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713685
13686 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613687 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713688 };
13689
rch8e6c6c42015-05-01 14:05:1313690 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13691 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713692 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713693
[email protected]49639fa2011-12-20 23:22:4113694 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713695
danakj1fd259a02016-04-16 03:17:0913696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713698
tfarina42834112016-09-22 13:38:2013699 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13701 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713702}
[email protected]65d34382010-07-01 18:12:2613703
[email protected]795cbf82013-07-22 09:37:2713704// A subclass of HttpAuthHandlerMock that records the request URL when
13705// it gets it. This is needed since the auth handler may get destroyed
13706// before we get a chance to query it.
13707class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13708 public:
13709 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13710
Chris Watkins7a41d3552017-12-01 02:13:2713711 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713712
13713 protected:
dchengb03027d2014-10-21 12:00:2013714 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13715 const HttpRequestInfo* request,
13716 const CompletionCallback& callback,
13717 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713718 *url_ = request->url;
13719 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13720 credentials, request, callback, auth_token);
13721 }
13722
13723 private:
13724 GURL* url_;
13725};
13726
[email protected]8e6441ca2010-08-19 05:56:3813727// Test that if we cancel the transaction as the connection is completing, that
13728// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113729TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813730 // Setup everything about the connection to complete synchronously, so that
13731 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13732 // for is the callback from the HttpStreamRequest.
13733 // Then cancel the transaction.
13734 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613735 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813736 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613737 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13738 MockRead(SYNCHRONOUS, "hello world"),
13739 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813740 };
13741
[email protected]8e6441ca2010-08-19 05:56:3813742 HttpRequestInfo request;
13743 request.method = "GET";
bncce36dca22015-04-21 22:11:2313744 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013745 request.traffic_annotation =
13746 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813747
[email protected]bb88e1d32013-05-03 23:11:0713748 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913749 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813750 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913751 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713752
[email protected]8e6441ca2010-08-19 05:56:3813753 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13754 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713755 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813756
[email protected]49639fa2011-12-20 23:22:4113757 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813758
vishal.b62985ca92015-04-17 08:45:5113759 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113760 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813762 trans.reset(); // Cancel the transaction here.
13763
fdoray92e35a72016-06-10 15:54:5513764 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013765}
13766
[email protected]ecab6e052014-05-16 14:58:1213767// Test that if a transaction is cancelled after receiving the headers, the
13768// stream is drained properly and added back to the socket pool. The main
13769// purpose of this test is to make sure that an HttpStreamParser can be read
13770// from after the HttpNetworkTransaction and the objects it owns have been
13771// deleted.
13772// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113773TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213774 MockRead data_reads[] = {
13775 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13776 MockRead(ASYNC, "Content-Length: 2\r\n"),
13777 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13778 MockRead(ASYNC, "1"),
13779 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13780 // HttpNetworkTransaction has been deleted.
13781 MockRead(ASYNC, "2"),
13782 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13783 };
13784 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13785 session_deps_.socket_factory->AddSocketDataProvider(&data);
13786
danakj1fd259a02016-04-16 03:17:0913787 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213788
13789 {
13790 HttpRequestInfo request;
13791 request.method = "GET";
bncce36dca22015-04-21 22:11:2313792 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013793 request.traffic_annotation =
13794 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213795
dcheng48459ac22014-08-26 00:46:4113796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213797 TestCompletionCallback callback;
13798
tfarina42834112016-09-22 13:38:2013799 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213801 callback.WaitForResult();
13802
13803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213804 ASSERT_TRUE(response);
13805 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213806 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13807
13808 // The transaction and HttpRequestInfo are deleted.
13809 }
13810
13811 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513812 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213813
13814 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113815 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213816}
13817
[email protected]76a505b2010-08-25 06:23:0013818// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113819TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913820 session_deps_.proxy_resolution_service =
13821 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113822 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713823 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013825
[email protected]76a505b2010-08-25 06:23:0013826 HttpRequestInfo request;
13827 request.method = "GET";
bncce36dca22015-04-21 22:11:2313828 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013829 request.traffic_annotation =
13830 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013831
13832 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313833 MockWrite(
13834 "GET http://www.example.org/ HTTP/1.1\r\n"
13835 "Host: www.example.org\r\n"
13836 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013837 };
13838
13839 MockRead data_reads1[] = {
13840 MockRead("HTTP/1.1 200 OK\r\n"),
13841 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13842 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613843 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013844 };
13845
13846 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13847 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713848 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013849
[email protected]49639fa2011-12-20 23:22:4113850 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013851
bnc691fda62016-08-12 00:43:1613852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913853 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613854 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913855 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13856 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013857
bnc691fda62016-08-12 00:43:1613858 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113859 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013860
13861 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113862 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013863
bnc691fda62016-08-12 00:43:1613864 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213865 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013866
13867 EXPECT_TRUE(response->headers->IsKeepAlive());
13868 EXPECT_EQ(200, response->headers->response_code());
13869 EXPECT_EQ(100, response->headers->GetContentLength());
13870 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713871 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13872 HostPortPair::FromString("myproxy:70")),
13873 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913874 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13875 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13876 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013877 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013878
13879 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613880 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013881 TestLoadTimingNotReusedWithPac(load_timing_info,
13882 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013883}
13884
13885// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113886TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913887 session_deps_.proxy_resolution_service =
13888 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113889 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713890 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013892
[email protected]76a505b2010-08-25 06:23:0013893 HttpRequestInfo request;
13894 request.method = "GET";
bncce36dca22015-04-21 22:11:2313895 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013896 request.traffic_annotation =
13897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013898
13899 // Since we have proxy, should try to establish tunnel.
13900 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713901 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13902 "Host: www.example.org:443\r\n"
13903 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013904
rsleevidb16bb02015-11-12 23:47:1713905 MockWrite("GET / HTTP/1.1\r\n"
13906 "Host: www.example.org\r\n"
13907 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013908 };
13909
13910 MockRead data_reads1[] = {
13911 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13912
13913 MockRead("HTTP/1.1 200 OK\r\n"),
13914 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13915 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613916 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013917 };
13918
13919 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13920 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713921 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613922 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713923 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013924
[email protected]49639fa2011-12-20 23:22:4113925 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013926
bnc691fda62016-08-12 00:43:1613927 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913928 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613929 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913930 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13931 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013932
bnc691fda62016-08-12 00:43:1613933 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013935
13936 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113937 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613938 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013939 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013940 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013941 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13942 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013943 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013944 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013945 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13946 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013947
bnc691fda62016-08-12 00:43:1613948 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213949 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013950
13951 EXPECT_TRUE(response->headers->IsKeepAlive());
13952 EXPECT_EQ(200, response->headers->response_code());
13953 EXPECT_EQ(100, response->headers->GetContentLength());
13954 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13955 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713956 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13957 HostPortPair::FromString("myproxy:70")),
13958 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913959 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13960 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13961 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013962
13963 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613964 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013965 TestLoadTimingNotReusedWithPac(load_timing_info,
13966 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013967}
13968
rsleevidb16bb02015-11-12 23:47:1713969// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13970// literal host.
bncd16676a2016-07-20 16:23:0113971TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913972 session_deps_.proxy_resolution_service =
13973 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
rsleevidb16bb02015-11-12 23:47:1713974 BoundTestNetLog log;
13975 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713977
13978 HttpRequestInfo request;
13979 request.method = "GET";
13980 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1013981 request.traffic_annotation =
13982 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713983
13984 // Since we have proxy, should try to establish tunnel.
13985 MockWrite data_writes1[] = {
13986 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13987 "Host: [::1]:443\r\n"
13988 "Proxy-Connection: keep-alive\r\n\r\n"),
13989
13990 MockWrite("GET / HTTP/1.1\r\n"
13991 "Host: [::1]\r\n"
13992 "Connection: keep-alive\r\n\r\n"),
13993 };
13994
13995 MockRead data_reads1[] = {
13996 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13997
13998 MockRead("HTTP/1.1 200 OK\r\n"),
13999 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14000 MockRead("Content-Length: 100\r\n\r\n"),
14001 MockRead(SYNCHRONOUS, OK),
14002 };
14003
14004 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14005 data_writes1, arraysize(data_writes1));
14006 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14007 SSLSocketDataProvider ssl(ASYNC, OK);
14008 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14009
14010 TestCompletionCallback callback1;
14011
bnc691fda62016-08-12 00:43:1614012 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714013
bnc691fda62016-08-12 00:43:1614014 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714016
14017 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114018 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714019 TestNetLogEntry::List entries;
14020 log.GetEntries(&entries);
14021 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014022 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14023 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714024 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014025 entries, pos,
14026 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14027 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714028
bnc691fda62016-08-12 00:43:1614029 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214030 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714031
14032 EXPECT_TRUE(response->headers->IsKeepAlive());
14033 EXPECT_EQ(200, response->headers->response_code());
14034 EXPECT_EQ(100, response->headers->GetContentLength());
14035 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14036 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714037 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14038 HostPortPair::FromString("myproxy:70")),
14039 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714040
14041 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614042 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714043 TestLoadTimingNotReusedWithPac(load_timing_info,
14044 CONNECT_TIMING_HAS_SSL_TIMES);
14045}
14046
[email protected]76a505b2010-08-25 06:23:0014047// Test a basic HTTPS GET request through a proxy, but the server hangs up
14048// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114049TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Lily Houghton8c2f97d2018-01-22 05:06:5914050 session_deps_.proxy_resolution_service =
14051 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5114052 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714053 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914054 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014055
[email protected]76a505b2010-08-25 06:23:0014056 HttpRequestInfo request;
14057 request.method = "GET";
bncce36dca22015-04-21 22:11:2314058 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014059 request.traffic_annotation =
14060 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014061
14062 // Since we have proxy, should try to establish tunnel.
14063 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714064 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14065 "Host: www.example.org:443\r\n"
14066 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014067
rsleevidb16bb02015-11-12 23:47:1714068 MockWrite("GET / HTTP/1.1\r\n"
14069 "Host: www.example.org\r\n"
14070 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014071 };
14072
14073 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014074 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614075 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014076 };
14077
14078 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14079 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714080 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614081 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714082 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014083
[email protected]49639fa2011-12-20 23:22:4114084 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014085
bnc691fda62016-08-12 00:43:1614086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014087
bnc691fda62016-08-12 00:43:1614088 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014090
14091 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114092 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614093 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014094 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014095 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014096 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14097 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014098 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014099 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014100 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14101 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014102}
14103
[email protected]749eefa82010-09-13 22:14:0314104// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114105TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114106 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914107 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114108 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314109
bnc42331402016-07-25 13:36:1514110 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114111 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314112 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114113 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314114 };
14115
rch8e6c6c42015-05-01 14:05:1314116 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
14117 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714118 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314119
[email protected]8ddf8322012-02-23 18:08:0614120 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614121 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714122 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314123
danakj1fd259a02016-04-16 03:17:0914124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314125
14126 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314127 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014128 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414129 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714130 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214131 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314132
14133 HttpRequestInfo request;
14134 request.method = "GET";
bncce36dca22015-04-21 22:11:2314135 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014136 request.traffic_annotation =
14137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314138
14139 // This is the important line that marks this as a preconnect.
14140 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14141
bnc691fda62016-08-12 00:43:1614142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314143
[email protected]41d64e82013-07-03 22:44:2614144 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014145 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14147 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314148}
14149
[email protected]73b8dd222010-11-11 19:55:2414150// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614151// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214152void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714153 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914154 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714155 request_info.url = GURL("https://www.example.com/");
14156 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914157 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014158 request_info.traffic_annotation =
14159 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714160
[email protected]8ddf8322012-02-23 18:08:0614161 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914162 MockWrite data_writes[] = {
14163 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414164 };
ttuttle859dc7a2015-04-23 19:42:2914165 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0714166 session_deps_.socket_factory->AddSocketDataProvider(&data);
14167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414168
danakj1fd259a02016-04-16 03:17:0914169 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614170 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414171
[email protected]49639fa2011-12-20 23:22:4114172 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014173 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914174 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414175 rv = callback.WaitForResult();
14176 ASSERT_EQ(error, rv);
14177}
14178
bncd16676a2016-07-20 16:23:0114179TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414180 // Just check a grab bag of cert errors.
14181 static const int kErrors[] = {
14182 ERR_CERT_COMMON_NAME_INVALID,
14183 ERR_CERT_AUTHORITY_INVALID,
14184 ERR_CERT_DATE_INVALID,
14185 };
14186 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614187 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14188 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414189 }
14190}
14191
[email protected]bd0b6772011-01-11 19:59:3014192// Ensure that a client certificate is removed from the SSL client auth
14193// cache when:
14194// 1) No proxy is involved.
14195// 2) TLS False Start is disabled.
14196// 3) The initial TLS handshake requests a client certificate.
14197// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114198TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914199 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714200 request_info.url = GURL("https://www.example.com/");
14201 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914202 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014203 request_info.traffic_annotation =
14204 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714205
[email protected]bd0b6772011-01-11 19:59:3014206 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114207 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014208
14209 // [ssl_]data1 contains the data for the first SSL handshake. When a
14210 // CertificateRequest is received for the first time, the handshake will
14211 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914212 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014213 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914215 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714216 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014217
14218 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14219 // False Start is not being used, the result of the SSL handshake will be
14220 // returned as part of the SSLClientSocket::Connect() call. This test
14221 // matches the result of a server sending a handshake_failure alert,
14222 // rather than a Finished message, because it requires a client
14223 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914224 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014225 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914227 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714228 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014229
14230 // [ssl_]data3 contains the data for the third SSL handshake. When a
14231 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214232 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14233 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014234 // of the HttpNetworkTransaction. Because this test failure is due to
14235 // requiring a client certificate, this fallback handshake should also
14236 // fail.
ttuttle859dc7a2015-04-23 19:42:2914237 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014238 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714239 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914240 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714241 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014242
[email protected]80c75f682012-05-26 16:22:1714243 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14244 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214245 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14246 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714247 // of the HttpNetworkTransaction. Because this test failure is due to
14248 // requiring a client certificate, this fallback handshake should also
14249 // fail.
ttuttle859dc7a2015-04-23 19:42:2914250 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714251 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714252 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914253 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714254 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714255
danakj1fd259a02016-04-16 03:17:0914256 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614257 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014258
[email protected]bd0b6772011-01-11 19:59:3014259 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114260 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014261 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114262 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014263
14264 // Complete the SSL handshake, which should abort due to requiring a
14265 // client certificate.
14266 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114267 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014268
14269 // Indicate that no certificate should be supplied. From the perspective
14270 // of SSLClientCertCache, NULL is just as meaningful as a real
14271 // certificate, so this is the same as supply a
14272 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614273 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114274 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014275
14276 // Ensure the certificate was added to the client auth cache before
14277 // allowing the connection to continue restarting.
14278 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414279 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114280 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414281 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214282 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014283
14284 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714285 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14286 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114288 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014289
14290 // Ensure that the client certificate is removed from the cache on a
14291 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114292 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414293 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014294}
14295
14296// Ensure that a client certificate is removed from the SSL client auth
14297// cache when:
14298// 1) No proxy is involved.
14299// 2) TLS False Start is enabled.
14300// 3) The initial TLS handshake requests a client certificate.
14301// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114302TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914303 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714304 request_info.url = GURL("https://www.example.com/");
14305 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914306 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014307 request_info.traffic_annotation =
14308 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714309
[email protected]bd0b6772011-01-11 19:59:3014310 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114311 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014312
14313 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14314 // return successfully after reading up to the peer's Certificate message.
14315 // This is to allow the caller to call SSLClientSocket::Write(), which can
14316 // enqueue application data to be sent in the same packet as the
14317 // ChangeCipherSpec and Finished messages.
14318 // The actual handshake will be finished when SSLClientSocket::Read() is
14319 // called, which expects to process the peer's ChangeCipherSpec and
14320 // Finished messages. If there was an error negotiating with the peer,
14321 // such as due to the peer requiring a client certificate when none was
14322 // supplied, the alert sent by the peer won't be processed until Read() is
14323 // called.
14324
14325 // Like the non-False Start case, when a client certificate is requested by
14326 // the peer, the handshake is aborted during the Connect() call.
14327 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914328 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014329 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914331 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714332 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014333
14334 // When a client certificate is supplied, Connect() will not be aborted
14335 // when the peer requests the certificate. Instead, the handshake will
14336 // artificially succeed, allowing the caller to write the HTTP request to
14337 // the socket. The handshake messages are not processed until Read() is
14338 // called, which then detects that the handshake was aborted, due to the
14339 // peer sending a handshake_failure because it requires a client
14340 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914341 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014342 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714343 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914344 MockRead data2_reads[] = {
14345 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014346 };
ttuttle859dc7a2015-04-23 19:42:2914347 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714348 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014349
14350 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714351 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14352 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914353 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014354 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714355 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914356 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714357 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014358
[email protected]80c75f682012-05-26 16:22:1714359 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14360 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914361 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714362 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914364 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714365 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714366
[email protected]7799de12013-05-30 05:52:5114367 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914368 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114369 ssl_data5.cert_request_info = cert_request.get();
14370 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914371 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114372 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14373
danakj1fd259a02016-04-16 03:17:0914374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014376
[email protected]bd0b6772011-01-11 19:59:3014377 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114378 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014379 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114380 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014381
14382 // Complete the SSL handshake, which should abort due to requiring a
14383 // client certificate.
14384 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114385 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014386
14387 // Indicate that no certificate should be supplied. From the perspective
14388 // of SSLClientCertCache, NULL is just as meaningful as a real
14389 // certificate, so this is the same as supply a
14390 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614391 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114392 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014393
14394 // Ensure the certificate was added to the client auth cache before
14395 // allowing the connection to continue restarting.
14396 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414397 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114398 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414399 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214400 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014401
[email protected]bd0b6772011-01-11 19:59:3014402 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714403 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14404 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014405 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114406 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014407
14408 // Ensure that the client certificate is removed from the cache on a
14409 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114410 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414411 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014412}
14413
[email protected]8c405132011-01-11 22:03:1814414// Ensure that a client certificate is removed from the SSL client auth
14415// cache when:
14416// 1) An HTTPS proxy is involved.
14417// 3) The HTTPS proxy requests a client certificate.
14418// 4) The client supplies an invalid/unacceptable certificate for the
14419// proxy.
14420// The test is repeated twice, first for connecting to an HTTPS endpoint,
14421// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114422TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Lily Houghton8c2f97d2018-01-22 05:06:5914423 session_deps_.proxy_resolution_service =
14424 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114425 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714426 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814427
14428 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114429 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814430
14431 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14432 // [ssl_]data[1-3]. Rather than represending the endpoint
14433 // (www.example.com:443), they represent failures with the HTTPS proxy
14434 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914435 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814436 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914438 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714439 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814440
ttuttle859dc7a2015-04-23 19:42:2914441 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814442 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714443 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914444 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714445 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814446
[email protected]80c75f682012-05-26 16:22:1714447 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14448#if 0
ttuttle859dc7a2015-04-23 19:42:2914449 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814450 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714451 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914452 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714453 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714454#endif
[email protected]8c405132011-01-11 22:03:1814455
ttuttle859dc7a2015-04-23 19:42:2914456 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814457 requests[0].url = GURL("https://www.example.com/");
14458 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914459 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014460 requests[0].traffic_annotation =
14461 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814462
14463 requests[1].url = GURL("http://www.example.com/");
14464 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914465 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014466 requests[1].traffic_annotation =
14467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814468
14469 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714470 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814473
14474 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114475 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014476 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114477 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814478
14479 // Complete the SSL handshake, which should abort due to requiring a
14480 // client certificate.
14481 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114482 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814483
14484 // Indicate that no certificate should be supplied. From the perspective
14485 // of SSLClientCertCache, NULL is just as meaningful as a real
14486 // certificate, so this is the same as supply a
14487 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614488 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114489 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814490
14491 // Ensure the certificate was added to the client auth cache before
14492 // allowing the connection to continue restarting.
14493 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414494 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114495 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414496 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214497 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814498 // Ensure the certificate was NOT cached for the endpoint. This only
14499 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114500 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414501 HostPortPair("www.example.com", 443), &client_cert,
14502 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814503
14504 // Restart the handshake. This will consume ssl_data2, which fails, and
14505 // then consume ssl_data3, which should also fail. The result code is
14506 // checked against what ssl_data3 should return.
14507 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114508 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814509
14510 // Now that the new handshake has failed, ensure that the client
14511 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114512 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414513 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114514 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414515 HostPortPair("www.example.com", 443), &client_cert,
14516 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814517 }
14518}
14519
bncd16676a2016-07-20 16:23:0114520TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614521 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914522 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914523 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614524
bnc032658ba2016-09-26 18:17:1514525 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614526
bncdf80d44fd2016-07-15 20:27:4114527 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914528 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814529 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114530 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714531 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614532 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114533 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614534 };
bnc42331402016-07-25 13:36:1514535 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114536 SpdySerializedFrame host1_resp_body(
14537 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514538 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114539 SpdySerializedFrame host2_resp_body(
14540 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614541 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114542 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14543 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314544 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614545 };
14546
eroman36d84e54432016-03-17 03:23:0214547 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214548 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314549 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14550 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714551 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614552
[email protected]aa22b242011-11-16 18:58:2914553 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614554 HttpRequestInfo request1;
14555 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314556 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614557 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014558 request1.traffic_annotation =
14559 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014560 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614561
tfarina42834112016-09-22 13:38:2014562 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14564 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614565
14566 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214567 ASSERT_TRUE(response);
14568 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214569 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614570
14571 std::string response_data;
robpercival214763f2016-07-01 23:27:0114572 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614573 EXPECT_EQ("hello!", response_data);
14574
bnca4d611d2016-09-22 19:55:3714575 // Preload mail.example.com into HostCache.
14576 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014577 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614578 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014579 std::unique_ptr<HostResolver::Request> request;
14580 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14581 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014582 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714584 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114585 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614586
14587 HttpRequestInfo request2;
14588 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714589 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614590 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014591 request2.traffic_annotation =
14592 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014593 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614594
tfarina42834112016-09-22 13:38:2014595 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14597 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614598
14599 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214600 ASSERT_TRUE(response);
14601 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214602 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614603 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214604 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114605 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614606 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614607}
14608
bncd16676a2016-07-20 16:23:0114609TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214610 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914611 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214613
bnc032658ba2016-09-26 18:17:1514614 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214615
bncdf80d44fd2016-07-15 20:27:4114616 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914617 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814618 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114619 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714620 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214621 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114622 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214623 };
bnc42331402016-07-25 13:36:1514624 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114625 SpdySerializedFrame host1_resp_body(
14626 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514627 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114628 SpdySerializedFrame host2_resp_body(
14629 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214630 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114631 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14632 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314633 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214634 };
14635
eroman36d84e54432016-03-17 03:23:0214636 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214637 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314638 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14639 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714640 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214641
14642 TestCompletionCallback callback;
14643 HttpRequestInfo request1;
14644 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314645 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214646 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014647 request1.traffic_annotation =
14648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014649 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214650
tfarina42834112016-09-22 13:38:2014651 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14653 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214654
14655 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214656 ASSERT_TRUE(response);
14657 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214658 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214659
14660 std::string response_data;
robpercival214763f2016-07-01 23:27:0114661 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214662 EXPECT_EQ("hello!", response_data);
14663
14664 HttpRequestInfo request2;
14665 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714666 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214667 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014668 request2.traffic_annotation =
14669 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014670 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214671
tfarina42834112016-09-22 13:38:2014672 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14674 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214675
14676 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214677 ASSERT_TRUE(response);
14678 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214679 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214680 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214681 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114682 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214683 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214684}
14685
bnc8016c1f2017-03-31 02:11:2914686// Regression test for https://crbug.com/546991.
14687// The server might not be able to serve an IP pooled request, and might send a
14688// 421 Misdirected Request response status to indicate this.
14689// HttpNetworkTransaction should reset the request and retry without IP pooling.
14690TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14691 // Two hosts resolve to the same IP address.
14692 const std::string ip_addr = "1.2.3.4";
14693 IPAddress ip;
14694 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14695 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14696
Jeremy Roman0579ed62017-08-29 15:56:1914697 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914698 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14699 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14700
14701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14702
14703 // Two requests on the first connection.
14704 SpdySerializedFrame req1(
14705 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14706 spdy_util_.UpdateWithStreamDestruction(1);
14707 SpdySerializedFrame req2(
14708 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14709 SpdySerializedFrame rst(
14710 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14711 MockWrite writes1[] = {
14712 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14713 CreateMockWrite(rst, 6),
14714 };
14715
14716 // The first one succeeds, the second gets error 421 Misdirected Request.
14717 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14718 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14719 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714720 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914721 SpdySerializedFrame resp2(
14722 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14723 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14724 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14725
14726 MockConnect connect1(ASYNC, OK, peer_addr);
14727 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14728 arraysize(writes1));
14729 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14730
14731 AddSSLSocketData();
14732
14733 // Retry the second request on a second connection.
14734 SpdyTestUtil spdy_util2;
14735 SpdySerializedFrame req3(
14736 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14737 MockWrite writes2[] = {
14738 CreateMockWrite(req3, 0),
14739 };
14740
14741 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14742 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14743 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14744 MockRead(ASYNC, 0, 3)};
14745
14746 MockConnect connect2(ASYNC, OK, peer_addr);
14747 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14748 arraysize(writes2));
14749 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14750
14751 AddSSLSocketData();
14752
14753 // Preload mail.example.org into HostCache.
14754 HostPortPair host_port("mail.example.org", 443);
14755 HostResolver::RequestInfo resolve_info(host_port);
14756 AddressList ignored;
14757 std::unique_ptr<HostResolver::Request> request;
14758 TestCompletionCallback callback;
14759 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14760 &ignored, callback.callback(),
14761 &request, NetLogWithSource());
14762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14763 rv = callback.WaitForResult();
14764 EXPECT_THAT(rv, IsOk());
14765
14766 HttpRequestInfo request1;
14767 request1.method = "GET";
14768 request1.url = GURL("https://www.example.org/");
14769 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014770 request1.traffic_annotation =
14771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914772 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14773
14774 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14775 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14776 rv = callback.WaitForResult();
14777 EXPECT_THAT(rv, IsOk());
14778
14779 const HttpResponseInfo* response = trans1.GetResponseInfo();
14780 ASSERT_TRUE(response);
14781 ASSERT_TRUE(response->headers);
14782 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14783 EXPECT_TRUE(response->was_fetched_via_spdy);
14784 EXPECT_TRUE(response->was_alpn_negotiated);
14785 std::string response_data;
14786 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14787 EXPECT_EQ("hello!", response_data);
14788
14789 HttpRequestInfo request2;
14790 request2.method = "GET";
14791 request2.url = GURL("https://mail.example.org/");
14792 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014793 request2.traffic_annotation =
14794 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914795 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14796
14797 BoundTestNetLog log;
14798 rv = trans2.Start(&request2, callback.callback(), log.bound());
14799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14800 rv = callback.WaitForResult();
14801 EXPECT_THAT(rv, IsOk());
14802
14803 response = trans2.GetResponseInfo();
14804 ASSERT_TRUE(response);
14805 ASSERT_TRUE(response->headers);
14806 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14807 EXPECT_TRUE(response->was_fetched_via_spdy);
14808 EXPECT_TRUE(response->was_alpn_negotiated);
14809 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14810 EXPECT_EQ("hello!", response_data);
14811
14812 TestNetLogEntry::List entries;
14813 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914814 ExpectLogContainsSomewhere(
14815 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914816 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914817}
14818
14819// Test that HTTP 421 responses are properly returned to the caller if received
14820// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14821// portions of the response.
14822TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14823 // Two hosts resolve to the same IP address.
14824 const std::string ip_addr = "1.2.3.4";
14825 IPAddress ip;
14826 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14827 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14828
Jeremy Roman0579ed62017-08-29 15:56:1914829 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914830 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14831 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14832
14833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14834
14835 // Two requests on the first connection.
14836 SpdySerializedFrame req1(
14837 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14838 spdy_util_.UpdateWithStreamDestruction(1);
14839 SpdySerializedFrame req2(
14840 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14841 SpdySerializedFrame rst(
14842 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14843 MockWrite writes1[] = {
14844 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14845 CreateMockWrite(rst, 6),
14846 };
14847
14848 // The first one succeeds, the second gets error 421 Misdirected Request.
14849 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14850 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14851 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714852 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914853 SpdySerializedFrame resp2(
14854 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14855 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14856 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14857
14858 MockConnect connect1(ASYNC, OK, peer_addr);
14859 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14860 arraysize(writes1));
14861 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14862
14863 AddSSLSocketData();
14864
14865 // Retry the second request on a second connection. It returns 421 Misdirected
14866 // Retry again.
14867 SpdyTestUtil spdy_util2;
14868 SpdySerializedFrame req3(
14869 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14870 MockWrite writes2[] = {
14871 CreateMockWrite(req3, 0),
14872 };
14873
14874 SpdySerializedFrame resp3(
14875 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14876 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14877 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14878 MockRead(ASYNC, 0, 3)};
14879
14880 MockConnect connect2(ASYNC, OK, peer_addr);
14881 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14882 arraysize(writes2));
14883 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14884
14885 AddSSLSocketData();
14886
14887 // Preload mail.example.org into HostCache.
14888 HostPortPair host_port("mail.example.org", 443);
14889 HostResolver::RequestInfo resolve_info(host_port);
14890 AddressList ignored;
14891 std::unique_ptr<HostResolver::Request> request;
14892 TestCompletionCallback callback;
14893 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14894 &ignored, callback.callback(),
14895 &request, NetLogWithSource());
14896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14897 rv = callback.WaitForResult();
14898 EXPECT_THAT(rv, IsOk());
14899
14900 HttpRequestInfo request1;
14901 request1.method = "GET";
14902 request1.url = GURL("https://www.example.org/");
14903 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014904 request1.traffic_annotation =
14905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914906 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14907
14908 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14910 rv = callback.WaitForResult();
14911 EXPECT_THAT(rv, IsOk());
14912
14913 const HttpResponseInfo* response = trans1.GetResponseInfo();
14914 ASSERT_TRUE(response);
14915 ASSERT_TRUE(response->headers);
14916 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14917 EXPECT_TRUE(response->was_fetched_via_spdy);
14918 EXPECT_TRUE(response->was_alpn_negotiated);
14919 std::string response_data;
14920 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14921 EXPECT_EQ("hello!", response_data);
14922
14923 HttpRequestInfo request2;
14924 request2.method = "GET";
14925 request2.url = GURL("https://mail.example.org/");
14926 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014927 request2.traffic_annotation =
14928 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914929 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14930
14931 BoundTestNetLog log;
14932 rv = trans2.Start(&request2, callback.callback(), log.bound());
14933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14934 rv = callback.WaitForResult();
14935 EXPECT_THAT(rv, IsOk());
14936
14937 // After a retry, the 421 Misdirected Request is reported back up to the
14938 // caller.
14939 response = trans2.GetResponseInfo();
14940 ASSERT_TRUE(response);
14941 ASSERT_TRUE(response->headers);
14942 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14943 EXPECT_TRUE(response->was_fetched_via_spdy);
14944 EXPECT_TRUE(response->was_alpn_negotiated);
14945 EXPECT_TRUE(response->ssl_info.cert);
14946 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14947 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914948}
14949
bnc6dcd8192017-05-25 20:11:5014950class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614951 public:
14952 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014953 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714954 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614955
dchengb03027d2014-10-21 12:00:2014956 int ResolveFromCache(const RequestInfo& info,
14957 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014958 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014959 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014960 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014961 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614962 return rv;
14963 }
14964
[email protected]e3ceb682011-06-28 23:55:4614965 private:
[email protected]e3ceb682011-06-28 23:55:4614966 const HostPortPair host_port_;
14967};
14968
bncd16676a2016-07-20 16:23:0114969TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314970 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614971 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914972 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714973 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614975
bnc032658ba2016-09-26 18:17:1514976 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614977
bncdf80d44fd2016-07-15 20:27:4114978 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914979 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814980 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114981 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714982 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614983 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114984 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614985 };
bnc42331402016-07-25 13:36:1514986 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114987 SpdySerializedFrame host1_resp_body(
14988 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514989 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114990 SpdySerializedFrame host2_resp_body(
14991 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614992 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114993 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14994 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314995 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614996 };
14997
eroman36d84e54432016-03-17 03:23:0214998 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214999 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1315000 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
15001 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0715002 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615003
[email protected]aa22b242011-11-16 18:58:2915004 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615005 HttpRequestInfo request1;
15006 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315007 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615008 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015009 request1.traffic_annotation =
15010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015011 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615012
tfarina42834112016-09-22 13:38:2015013 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15015 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615016
15017 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215018 ASSERT_TRUE(response);
15019 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215020 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615021
15022 std::string response_data;
robpercival214763f2016-07-01 23:27:0115023 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615024 EXPECT_EQ("hello!", response_data);
15025
15026 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715027 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615028 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015029 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015030 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15031 &ignored, callback.callback(),
15032 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715034 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115035 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615036
15037 HttpRequestInfo request2;
15038 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715039 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615040 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015041 request2.traffic_annotation =
15042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015043 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615044
tfarina42834112016-09-22 13:38:2015045 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15047 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615048
15049 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215050 ASSERT_TRUE(response);
15051 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215052 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615053 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215054 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115055 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615056 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615057}
15058
bncd16676a2016-07-20 16:23:0115059TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315060 const std::string https_url = "https://www.example.org:8080/";
15061 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415062
15063 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115064 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915065 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415066
15067 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115068 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415069 };
15070
bnc42331402016-07-25 13:36:1515071 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115072 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15073 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915074 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415075
rch8e6c6c42015-05-01 14:05:1315076 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15077 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415078 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715079 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415080
15081 // HTTP GET for the HTTP URL
15082 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315083 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415084 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315085 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415086 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415087 };
15088
15089 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315090 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15091 MockRead(ASYNC, 2, "hello"),
15092 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415093 };
15094
rch8e6c6c42015-05-01 14:05:1315095 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15096 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0415097
[email protected]8450d722012-07-02 19:14:0415098 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615099 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15101 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15102 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415103
danakj1fd259a02016-04-16 03:17:0915104 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415105
15106 // Start the first transaction to set up the SpdySession
15107 HttpRequestInfo request1;
15108 request1.method = "GET";
15109 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415110 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015111 request1.traffic_annotation =
15112 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015113 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415114 TestCompletionCallback callback1;
15115 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015116 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515117 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415118
robpercival214763f2016-07-01 23:27:0115119 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415120 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15121
15122 // Now, start the HTTP request
15123 HttpRequestInfo request2;
15124 request2.method = "GET";
15125 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415126 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015127 request2.traffic_annotation =
15128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015129 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415130 TestCompletionCallback callback2;
15131 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015132 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515133 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415134
robpercival214763f2016-07-01 23:27:0115135 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415136 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15137}
15138
bnc5452e2a2015-05-08 16:27:4215139// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15140// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115141TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515142 url::SchemeHostPort server("https", "www.example.org", 443);
15143 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215144
bnc8bef8da22016-05-30 01:28:2515145 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215146 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615147 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215148 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15149
15150 // No data should be read from the alternative, because HTTP/1.1 is
15151 // negotiated.
15152 StaticSocketDataProvider data;
15153 session_deps_.socket_factory->AddSocketDataProvider(&data);
15154
15155 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615156 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215157 // mocked. This way the request relies on the alternate Job.
15158 StaticSocketDataProvider data_refused;
15159 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15160 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15161
zhongyi3d4a55e72016-04-22 20:36:4615162 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015164 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215165 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115166 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215167 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115168 http_server_properties->SetHttp2AlternativeService(
15169 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215170
bnc5452e2a2015-05-08 16:27:4215171 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215173 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515174 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015175 request.traffic_annotation =
15176 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215177 TestCompletionCallback callback;
15178
15179 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215180 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015181 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215182 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215183}
15184
bnc40448a532015-05-11 19:13:1415185// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615186// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415187// succeeds, the request should succeed, even if the latter fails because
15188// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115189TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515190 url::SchemeHostPort server("https", "www.example.org", 443);
15191 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415192
15193 // Negotiate HTTP/1.1 with alternative.
15194 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615195 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415196 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15197
15198 // No data should be read from the alternative, because HTTP/1.1 is
15199 // negotiated.
15200 StaticSocketDataProvider data;
15201 session_deps_.socket_factory->AddSocketDataProvider(&data);
15202
zhongyi3d4a55e72016-04-22 20:36:4615203 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415204 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615205 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415206 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15207
15208 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515209 MockWrite("GET / HTTP/1.1\r\n"
15210 "Host: www.example.org\r\n"
15211 "Connection: keep-alive\r\n\r\n"),
15212 MockWrite("GET /second HTTP/1.1\r\n"
15213 "Host: www.example.org\r\n"
15214 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415215 };
15216
15217 MockRead http_reads[] = {
15218 MockRead("HTTP/1.1 200 OK\r\n"),
15219 MockRead("Content-Type: text/html\r\n"),
15220 MockRead("Content-Length: 6\r\n\r\n"),
15221 MockRead("foobar"),
15222 MockRead("HTTP/1.1 200 OK\r\n"),
15223 MockRead("Content-Type: text/html\r\n"),
15224 MockRead("Content-Length: 7\r\n\r\n"),
15225 MockRead("another"),
15226 };
15227 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15228 http_writes, arraysize(http_writes));
15229 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15230
zhongyi3d4a55e72016-04-22 20:36:4615231 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015233 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415234 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115235 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215236 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115237 http_server_properties->SetHttp2AlternativeService(
15238 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415239
15240 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15241 HttpRequestInfo request1;
15242 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515243 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415244 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015245 request1.traffic_annotation =
15246 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415247 TestCompletionCallback callback1;
15248
tfarina42834112016-09-22 13:38:2015249 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415250 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115251 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415252
15253 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215254 ASSERT_TRUE(response1);
15255 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415256 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15257
15258 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115259 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415260 EXPECT_EQ("foobar", response_data1);
15261
15262 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15263 // for alternative service.
15264 EXPECT_TRUE(
15265 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15266
zhongyi3d4a55e72016-04-22 20:36:4615267 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415268 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615269 // to server.
bnc40448a532015-05-11 19:13:1415270 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15271 HttpRequestInfo request2;
15272 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515273 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415274 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015275 request2.traffic_annotation =
15276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415277 TestCompletionCallback callback2;
15278
tfarina42834112016-09-22 13:38:2015279 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415280 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115281 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415282
15283 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215284 ASSERT_TRUE(response2);
15285 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415286 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15287
15288 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115289 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415290 EXPECT_EQ("another", response_data2);
15291}
15292
bnc5452e2a2015-05-08 16:27:4215293// Alternative service requires HTTP/2 (or SPDY), but there is already a
15294// HTTP/1.1 socket open to the alternative server. That socket should not be
15295// used.
bncd16676a2016-07-20 16:23:0115296TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615297 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215298 HostPortPair alternative("alternative.example.org", 443);
15299 std::string origin_url = "https://origin.example.org:443";
15300 std::string alternative_url = "https://alternative.example.org:443";
15301
15302 // Negotiate HTTP/1.1 with alternative.example.org.
15303 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615304 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15306
15307 // HTTP/1.1 data for |request1| and |request2|.
15308 MockWrite http_writes[] = {
15309 MockWrite(
15310 "GET / HTTP/1.1\r\n"
15311 "Host: alternative.example.org\r\n"
15312 "Connection: keep-alive\r\n\r\n"),
15313 MockWrite(
15314 "GET / HTTP/1.1\r\n"
15315 "Host: alternative.example.org\r\n"
15316 "Connection: keep-alive\r\n\r\n"),
15317 };
15318
15319 MockRead http_reads[] = {
15320 MockRead(
15321 "HTTP/1.1 200 OK\r\n"
15322 "Content-Type: text/html; charset=iso-8859-1\r\n"
15323 "Content-Length: 40\r\n\r\n"
15324 "first HTTP/1.1 response from alternative"),
15325 MockRead(
15326 "HTTP/1.1 200 OK\r\n"
15327 "Content-Type: text/html; charset=iso-8859-1\r\n"
15328 "Content-Length: 41\r\n\r\n"
15329 "second HTTP/1.1 response from alternative"),
15330 };
15331 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15332 http_writes, arraysize(http_writes));
15333 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15334
15335 // This test documents that an alternate Job should not pool to an already
15336 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615337 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215338 StaticSocketDataProvider data_refused;
15339 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15340 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15341
zhongyi3d4a55e72016-04-22 20:36:4615342 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915343 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015344 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215345 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115346 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215347 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115348 http_server_properties->SetHttp2AlternativeService(
15349 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215350
15351 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215352 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615353 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215354 request1.method = "GET";
15355 request1.url = GURL(alternative_url);
15356 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015357 request1.traffic_annotation =
15358 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215359 TestCompletionCallback callback1;
15360
tfarina42834112016-09-22 13:38:2015361 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115362 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615363 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215364 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215365 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215366 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215367 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215368 EXPECT_FALSE(response1->was_fetched_via_spdy);
15369 std::string response_data1;
bnc691fda62016-08-12 00:43:1615370 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215371 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15372
15373 // Request for origin.example.org, which has an alternative service. This
15374 // will start two Jobs: the alternative looks for connections to pool to,
15375 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615376 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215377 // this request fails.
bnc5452e2a2015-05-08 16:27:4215378 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615379 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215380 request2.method = "GET";
15381 request2.url = GURL(origin_url);
15382 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015383 request2.traffic_annotation =
15384 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215385 TestCompletionCallback callback2;
15386
tfarina42834112016-09-22 13:38:2015387 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115388 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215389
15390 // Another transaction to alternative. This is to test that the HTTP/1.1
15391 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215392 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615393 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215394 request3.method = "GET";
15395 request3.url = GURL(alternative_url);
15396 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015397 request3.traffic_annotation =
15398 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215399 TestCompletionCallback callback3;
15400
tfarina42834112016-09-22 13:38:2015401 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115402 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615403 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215404 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215405 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215406 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215407 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215408 EXPECT_FALSE(response3->was_fetched_via_spdy);
15409 std::string response_data3;
bnc691fda62016-08-12 00:43:1615410 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215411 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15412}
15413
bncd16676a2016-07-20 16:23:0115414TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315415 const std::string https_url = "https://www.example.org:8080/";
15416 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415417
rdsmithebb50aa2015-11-12 03:44:3815418 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115419 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815420
[email protected]8450d722012-07-02 19:14:0415421 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315422 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115423 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415424 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115425 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915426 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115427 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215428 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915429
15430 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915431 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715432 req2_block[kHttp2MethodHeader] = "GET";
15433 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15434 req2_block[kHttp2SchemeHeader] = "http";
15435 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115436 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515437 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415438
15439 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115440 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15441 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415442 };
15443
bncdf80d44fd2016-07-15 20:27:4115444 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515445 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115446 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515447 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115448 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15449 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815450 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115451 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815452 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515453 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115454 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315455 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115456 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315457 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115458 CreateMockRead(wrapped_resp1, 4),
15459 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315460 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115461 CreateMockRead(resp2, 8),
15462 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315463 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15464 };
[email protected]8450d722012-07-02 19:14:0415465
mmenke666a6fea2015-12-19 04:16:3315466 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15467 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415468 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715469 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415470
Lily Houghton8c2f97d2018-01-22 05:06:5915471 session_deps_.proxy_resolution_service =
15472 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115473 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715474 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415475 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615476 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315477 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415478 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615479 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15481 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415482
danakj1fd259a02016-04-16 03:17:0915483 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415484
15485 // Start the first transaction to set up the SpdySession
15486 HttpRequestInfo request1;
15487 request1.method = "GET";
15488 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415489 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015490 request1.traffic_annotation =
15491 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015492 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415493 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015494 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415495
mmenke666a6fea2015-12-19 04:16:3315496 // This pause is a hack to avoid running into https://crbug.com/497228.
15497 data1.RunUntilPaused();
15498 base::RunLoop().RunUntilIdle();
15499 data1.Resume();
robpercival214763f2016-07-01 23:27:0115500 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415501 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15502
[email protected]f6c63db52013-02-02 00:35:2215503 LoadTimingInfo load_timing_info1;
15504 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15505 TestLoadTimingNotReusedWithPac(load_timing_info1,
15506 CONNECT_TIMING_HAS_SSL_TIMES);
15507
mmenke666a6fea2015-12-19 04:16:3315508 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415509 HttpRequestInfo request2;
15510 request2.method = "GET";
15511 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415512 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015513 request2.traffic_annotation =
15514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015515 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415516 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015517 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415518
mmenke666a6fea2015-12-19 04:16:3315519 // This pause is a hack to avoid running into https://crbug.com/497228.
15520 data1.RunUntilPaused();
15521 base::RunLoop().RunUntilIdle();
15522 data1.Resume();
robpercival214763f2016-07-01 23:27:0115523 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315524
[email protected]8450d722012-07-02 19:14:0415525 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215526
15527 LoadTimingInfo load_timing_info2;
15528 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15529 // The established SPDY sessions is considered reused by the HTTP request.
15530 TestLoadTimingReusedWithPac(load_timing_info2);
15531 // HTTP requests over a SPDY session should have a different connection
15532 // socket_log_id than requests over a tunnel.
15533 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415534}
15535
[email protected]2d88e7d2012-07-19 17:55:1715536// Test that in the case where we have a SPDY session to a SPDY proxy
15537// that we do not pool other origins that resolve to the same IP when
15538// the certificate does not match the new origin.
15539// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115540TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315541 const std::string url1 = "http://www.example.org/";
15542 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715543 const std::string ip_addr = "1.2.3.4";
15544
rdsmithebb50aa2015-11-12 03:44:3815545 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115546 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815547
[email protected]2d88e7d2012-07-19 17:55:1715548 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615549 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315550 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115551 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515552 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715553
15554 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115555 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715556 };
15557
bnc42331402016-07-25 13:36:1515558 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115559 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715560 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115561 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15562 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715563 };
15564
mmenke666a6fea2015-12-19 04:16:3315565 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15566 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215567 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915568 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715569 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15570 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315571 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715572
15573 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115574 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915575 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715576
15577 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115578 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715579 };
15580
bnc42331402016-07-25 13:36:1515581 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115582 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15583 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315584 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715585
mmenke666a6fea2015-12-19 04:16:3315586 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15587 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715588 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315589 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715590
15591 // Set up a proxy config that sends HTTP requests to a proxy, and
15592 // all others direct.
15593 ProxyConfig proxy_config;
15594 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Lily Houghton8c2f97d2018-01-22 05:06:5915595 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1915596 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815597 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715598
bncce36dca22015-04-21 22:11:2315599 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615600 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715601 // Load a valid cert. Note, that this does not need to
15602 // be valid for proxy because the MockSSLClientSocket does
15603 // not actually verify it. But SpdySession will use this
15604 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915605 ssl1.ssl_info.cert =
15606 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15607 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15609 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715610
15611 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615612 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15614 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715615
Jeremy Roman0579ed62017-08-29 15:56:1915616 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315617 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715618 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715619
danakj1fd259a02016-04-16 03:17:0915620 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715621
15622 // Start the first transaction to set up the SpdySession
15623 HttpRequestInfo request1;
15624 request1.method = "GET";
15625 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715626 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015627 request1.traffic_annotation =
15628 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015629 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715630 TestCompletionCallback callback1;
15631 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015632 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315633 // This pause is a hack to avoid running into https://crbug.com/497228.
15634 data1.RunUntilPaused();
15635 base::RunLoop().RunUntilIdle();
15636 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715637
robpercival214763f2016-07-01 23:27:0115638 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715639 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15640
15641 // Now, start the HTTP request
15642 HttpRequestInfo request2;
15643 request2.method = "GET";
15644 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715645 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015646 request2.traffic_annotation =
15647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015648 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715649 TestCompletionCallback callback2;
15650 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015651 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515652 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715653
15654 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115655 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715656 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15657}
15658
[email protected]85f97342013-04-17 06:12:2415659// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15660// error) in SPDY session, removes the socket from pool and closes the SPDY
15661// session. Verify that new url's from the same HttpNetworkSession (and a new
15662// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115663TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315664 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415665
15666 MockRead reads1[] = {
15667 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15668 };
15669
mmenke11eb5152015-06-09 14:50:5015670 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415671
bncdf80d44fd2016-07-15 20:27:4115672 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915673 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415674 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115675 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415676 };
15677
bnc42331402016-07-25 13:36:1515678 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115679 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415680 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115681 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15682 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415683 };
15684
mmenke11eb5152015-06-09 14:50:5015685 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15686 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415687
[email protected]85f97342013-04-17 06:12:2415688 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615689 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015690 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15691 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415692
15693 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615694 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015695 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15696 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415697
danakj1fd259a02016-04-16 03:17:0915698 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015699 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415700
15701 // Start the first transaction to set up the SpdySession and verify that
15702 // connection was closed.
15703 HttpRequestInfo request1;
15704 request1.method = "GET";
15705 request1.url = GURL(https_url);
15706 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015707 request1.traffic_annotation =
15708 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015709 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415710 TestCompletionCallback callback1;
15711 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015712 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115713 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415714
15715 // Now, start the second request and make sure it succeeds.
15716 HttpRequestInfo request2;
15717 request2.method = "GET";
15718 request2.url = GURL(https_url);
15719 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015720 request2.traffic_annotation =
15721 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015722 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415723 TestCompletionCallback callback2;
15724 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015725 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415726
robpercival214763f2016-07-01 23:27:0115727 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415728 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15729}
15730
bncd16676a2016-07-20 16:23:0115731TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315732 ClientSocketPoolManager::set_max_sockets_per_group(
15733 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15734 ClientSocketPoolManager::set_max_sockets_per_pool(
15735 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15736
15737 // Use two different hosts with different IPs so they don't get pooled.
15738 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15739 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915740 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315741
15742 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615743 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315744 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615745 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315746 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15747 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15748
bncdf80d44fd2016-07-15 20:27:4115749 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915750 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315751 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115752 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315753 };
bnc42331402016-07-25 13:36:1515754 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115755 SpdySerializedFrame host1_resp_body(
15756 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315757 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115758 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915759 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315760 };
15761
rdsmithebb50aa2015-11-12 03:44:3815762 // Use a separate test instance for the separate SpdySession that will be
15763 // created.
bncd16676a2016-07-20 16:23:0115764 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915765 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815766 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15767 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315768 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15769
bncdf80d44fd2016-07-15 20:27:4115770 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915771 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315772 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115773 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315774 };
bnc42331402016-07-25 13:36:1515775 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115776 SpdySerializedFrame host2_resp_body(
15777 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315778 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115779 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915780 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315781 };
15782
Jeremy Roman0579ed62017-08-29 15:56:1915783 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815784 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15785 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315786 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15787
15788 MockWrite http_write[] = {
15789 MockWrite("GET / HTTP/1.1\r\n"
15790 "Host: www.a.com\r\n"
15791 "Connection: keep-alive\r\n\r\n"),
15792 };
15793
15794 MockRead http_read[] = {
15795 MockRead("HTTP/1.1 200 OK\r\n"),
15796 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15797 MockRead("Content-Length: 6\r\n\r\n"),
15798 MockRead("hello!"),
15799 };
15800 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15801 http_write, arraysize(http_write));
15802 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15803
15804 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415805 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15806 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315807 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615808 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315809
15810 TestCompletionCallback callback;
15811 HttpRequestInfo request1;
15812 request1.method = "GET";
15813 request1.url = GURL("https://www.a.com/");
15814 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015815 request1.traffic_annotation =
15816 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815817 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915818 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315819
tfarina42834112016-09-22 13:38:2015820 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15822 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315823
15824 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215825 ASSERT_TRUE(response);
15826 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215827 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315828 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215829 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315830
15831 std::string response_data;
robpercival214763f2016-07-01 23:27:0115832 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315833 EXPECT_EQ("hello!", response_data);
15834 trans.reset();
15835 EXPECT_TRUE(
[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 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415839 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15840 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315841 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615842 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315843 HttpRequestInfo request2;
15844 request2.method = "GET";
15845 request2.url = GURL("https://www.b.com/");
15846 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015847 request2.traffic_annotation =
15848 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815849 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915850 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315851
tfarina42834112016-09-22 13:38:2015852 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15854 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315855
15856 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215857 ASSERT_TRUE(response);
15858 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215859 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315860 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215861 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115862 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315863 EXPECT_EQ("hello!", response_data);
15864 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615865 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315866 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615867 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315868
15869 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415870 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15871 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315872 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615873 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315874 HttpRequestInfo request3;
15875 request3.method = "GET";
15876 request3.url = GURL("http://www.a.com/");
15877 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015878 request3.traffic_annotation =
15879 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815880 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915881 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315882
tfarina42834112016-09-22 13:38:2015883 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15885 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315886
15887 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215888 ASSERT_TRUE(response);
15889 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315890 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15891 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215892 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115893 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315894 EXPECT_EQ("hello!", response_data);
15895 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615896 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315897 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615898 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315899}
15900
bncd16676a2016-07-20 16:23:0115901TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415902 HttpRequestInfo request;
15903 request.method = "GET";
bncce36dca22015-04-21 22:11:2315904 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015905 request.traffic_annotation =
15906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415907
danakj1fd259a02016-04-16 03:17:0915908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415910
ttuttled9dbc652015-09-29 20:00:5915911 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415912 StaticSocketDataProvider data;
15913 data.set_connect_data(mock_connect);
15914 session_deps_.socket_factory->AddSocketDataProvider(&data);
15915
15916 TestCompletionCallback callback;
15917
tfarina42834112016-09-22 13:38:2015918 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415920
15921 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115922 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415923
[email protected]79e1fd62013-06-20 06:50:0415924 // We don't care whether this succeeds or fails, but it shouldn't crash.
15925 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615926 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715927
15928 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615929 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715930 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115931 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915932
15933 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615934 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915935 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415936}
15937
bncd16676a2016-07-20 16:23:0115938TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415939 HttpRequestInfo request;
15940 request.method = "GET";
bncce36dca22015-04-21 22:11:2315941 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015942 request.traffic_annotation =
15943 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415944
danakj1fd259a02016-04-16 03:17:0915945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415947
ttuttled9dbc652015-09-29 20:00:5915948 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415949 StaticSocketDataProvider data;
15950 data.set_connect_data(mock_connect);
15951 session_deps_.socket_factory->AddSocketDataProvider(&data);
15952
15953 TestCompletionCallback callback;
15954
tfarina42834112016-09-22 13:38:2015955 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415957
15958 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115959 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415960
[email protected]79e1fd62013-06-20 06:50:0415961 // We don't care whether this succeeds or fails, but it shouldn't crash.
15962 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615963 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715964
15965 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615966 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715967 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115968 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915969
15970 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615971 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915972 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415973}
15974
bncd16676a2016-07-20 16:23:0115975TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415976 HttpRequestInfo request;
15977 request.method = "GET";
bncce36dca22015-04-21 22:11:2315978 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015979 request.traffic_annotation =
15980 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415981
danakj1fd259a02016-04-16 03:17:0915982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415984
15985 MockWrite data_writes[] = {
15986 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15987 };
15988 MockRead data_reads[] = {
15989 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15990 };
15991
15992 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15993 data_writes, arraysize(data_writes));
15994 session_deps_.socket_factory->AddSocketDataProvider(&data);
15995
15996 TestCompletionCallback callback;
15997
tfarina42834112016-09-22 13:38:2015998 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416000
16001 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116002 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416003
[email protected]79e1fd62013-06-20 06:50:0416004 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616005 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416006 EXPECT_TRUE(request_headers.HasHeader("Host"));
16007}
16008
bncd16676a2016-07-20 16:23:0116009TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416010 HttpRequestInfo request;
16011 request.method = "GET";
bncce36dca22015-04-21 22:11:2316012 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016013 request.traffic_annotation =
16014 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416015
danakj1fd259a02016-04-16 03:17:0916016 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616017 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416018
16019 MockWrite data_writes[] = {
16020 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16021 };
16022 MockRead data_reads[] = {
16023 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16024 };
16025
16026 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16027 data_writes, arraysize(data_writes));
16028 session_deps_.socket_factory->AddSocketDataProvider(&data);
16029
16030 TestCompletionCallback callback;
16031
tfarina42834112016-09-22 13:38:2016032 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416034
16035 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116036 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416037
[email protected]79e1fd62013-06-20 06:50:0416038 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616039 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416040 EXPECT_TRUE(request_headers.HasHeader("Host"));
16041}
16042
bncd16676a2016-07-20 16:23:0116043TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416044 HttpRequestInfo request;
16045 request.method = "GET";
bncce36dca22015-04-21 22:11:2316046 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016047 request.traffic_annotation =
16048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416049
danakj1fd259a02016-04-16 03:17:0916050 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616051 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416052
16053 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316054 MockWrite(
16055 "GET / HTTP/1.1\r\n"
16056 "Host: www.example.org\r\n"
16057 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416058 };
16059 MockRead data_reads[] = {
16060 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16061 };
16062
16063 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16064 data_writes, arraysize(data_writes));
16065 session_deps_.socket_factory->AddSocketDataProvider(&data);
16066
16067 TestCompletionCallback callback;
16068
tfarina42834112016-09-22 13:38:2016069 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416071
16072 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116073 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416074
[email protected]79e1fd62013-06-20 06:50:0416075 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616076 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416077 EXPECT_TRUE(request_headers.HasHeader("Host"));
16078}
16079
bncd16676a2016-07-20 16:23:0116080TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416081 HttpRequestInfo request;
16082 request.method = "GET";
bncce36dca22015-04-21 22:11:2316083 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016084 request.traffic_annotation =
16085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416086
danakj1fd259a02016-04-16 03:17:0916087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416089
16090 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316091 MockWrite(
16092 "GET / HTTP/1.1\r\n"
16093 "Host: www.example.org\r\n"
16094 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416095 };
16096 MockRead data_reads[] = {
16097 MockRead(ASYNC, ERR_CONNECTION_RESET),
16098 };
16099
16100 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16101 data_writes, arraysize(data_writes));
16102 session_deps_.socket_factory->AddSocketDataProvider(&data);
16103
16104 TestCompletionCallback callback;
16105
tfarina42834112016-09-22 13:38:2016106 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416108
16109 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116110 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416111
[email protected]79e1fd62013-06-20 06:50:0416112 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616113 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416114 EXPECT_TRUE(request_headers.HasHeader("Host"));
16115}
16116
bncd16676a2016-07-20 16:23:0116117TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416118 HttpRequestInfo request;
16119 request.method = "GET";
bncce36dca22015-04-21 22:11:2316120 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416121 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016122 request.traffic_annotation =
16123 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416124
danakj1fd259a02016-04-16 03:17:0916125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416127
16128 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316129 MockWrite(
16130 "GET / HTTP/1.1\r\n"
16131 "Host: www.example.org\r\n"
16132 "Connection: keep-alive\r\n"
16133 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416134 };
16135 MockRead data_reads[] = {
16136 MockRead("HTTP/1.1 200 OK\r\n"
16137 "Content-Length: 5\r\n\r\n"
16138 "hello"),
16139 MockRead(ASYNC, ERR_UNEXPECTED),
16140 };
16141
16142 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16143 data_writes, arraysize(data_writes));
16144 session_deps_.socket_factory->AddSocketDataProvider(&data);
16145
16146 TestCompletionCallback callback;
16147
tfarina42834112016-09-22 13:38:2016148 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116149 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416150
16151 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116152 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416153
16154 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616155 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416156 std::string foo;
16157 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16158 EXPECT_EQ("bar", foo);
16159}
16160
[email protected]bf828982013-08-14 18:01:4716161namespace {
16162
yhiranoa7e05bb2014-11-06 05:40:3916163// Fake HttpStream that simply records calls to SetPriority().
16164class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0316165 public base::SupportsWeakPtr<FakeStream> {
16166 public:
16167 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2716168 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0316169
16170 RequestPriority priority() const { return priority_; }
16171
dchengb03027d2014-10-21 12:00:2016172 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716173 bool can_send_early,
dchengb03027d2014-10-21 12:00:2016174 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016175 const NetLogWithSource& net_log,
Bence Békya25e3f72018-02-13 21:13:3916176 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316177 return ERR_IO_PENDING;
16178 }
16179
dchengb03027d2014-10-21 12:00:2016180 int SendRequest(const HttpRequestHeaders& request_headers,
16181 HttpResponseInfo* response,
Bence Békya25e3f72018-02-13 21:13:3916182 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316183 ADD_FAILURE();
16184 return ERR_UNEXPECTED;
16185 }
16186
Bence Békya25e3f72018-02-13 21:13:3916187 int ReadResponseHeaders(CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316188 ADD_FAILURE();
16189 return ERR_UNEXPECTED;
16190 }
16191
dchengb03027d2014-10-21 12:00:2016192 int ReadResponseBody(IOBuffer* buf,
16193 int buf_len,
Bence Békya25e3f72018-02-13 21:13:3916194 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316195 ADD_FAILURE();
16196 return ERR_UNEXPECTED;
16197 }
16198
dchengb03027d2014-10-21 12:00:2016199 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0316200
dchengb03027d2014-10-21 12:00:2016201 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0316202 ADD_FAILURE();
16203 return false;
16204 }
16205
dchengb03027d2014-10-21 12:00:2016206 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0316207 ADD_FAILURE();
16208 return false;
16209 }
16210
dchengb03027d2014-10-21 12:00:2016211 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316212
mmenkebd84c392015-09-02 14:12:3416213 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0316214
sclittle4de1bab92015-09-22 21:28:2416215 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5916216 ADD_FAILURE();
16217 return 0;
16218 }
16219
sclittlebe1ccf62015-09-02 19:40:3616220 int64_t GetTotalSentBytes() const override {
16221 ADD_FAILURE();
16222 return 0;
16223 }
16224
dchengb03027d2014-10-21 12:00:2016225 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0316226 ADD_FAILURE();
16227 return false;
16228 }
16229
rchcd379012017-04-12 21:53:3216230 bool GetAlternativeService(
16231 AlternativeService* alternative_service) const override {
16232 ADD_FAILURE();
16233 return false;
16234 }
16235
dchengb03027d2014-10-21 12:00:2016236 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
16237
16238 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0316239 ADD_FAILURE();
16240 }
16241
ttuttled9dbc652015-09-29 20:00:5916242 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16243
nharper78e6d2b2016-09-21 05:42:3516244 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16245 TokenBindingType tb_type,
16246 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416247 ADD_FAILURE();
16248 return ERR_NOT_IMPLEMENTED;
16249 }
16250
dchengb03027d2014-10-21 12:00:2016251 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316252
zhongyica364fbb2015-12-12 03:39:1216253 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16254
dchengb03027d2014-10-21 12:00:2016255 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0316256
yhiranoa7e05bb2014-11-06 05:40:3916257 HttpStream* RenewStreamForAuth() override { return NULL; }
16258
Andrey Kosyakov83a6eee2017-08-14 19:20:0416259 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
16260
[email protected]e86839fd2013-08-14 18:29:0316261 private:
16262 RequestPriority priority_;
16263
16264 DISALLOW_COPY_AND_ASSIGN(FakeStream);
16265};
16266
16267// Fake HttpStreamRequest that simply records calls to SetPriority()
16268// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4716269class FakeStreamRequest : public HttpStreamRequest,
16270 public base::SupportsWeakPtr<FakeStreamRequest> {
16271 public:
[email protected]e86839fd2013-08-14 18:29:0316272 FakeStreamRequest(RequestPriority priority,
16273 HttpStreamRequest::Delegate* delegate)
16274 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4416275 delegate_(delegate),
16276 websocket_stream_create_helper_(NULL) {}
16277
16278 FakeStreamRequest(RequestPriority priority,
16279 HttpStreamRequest::Delegate* delegate,
16280 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
16281 : priority_(priority),
16282 delegate_(delegate),
16283 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0316284
Chris Watkins7a41d3552017-12-01 02:13:2716285 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4716286
16287 RequestPriority priority() const { return priority_; }
16288
[email protected]831e4a32013-11-14 02:14:4416289 const WebSocketHandshakeStreamBase::CreateHelper*
16290 websocket_stream_create_helper() const {
16291 return websocket_stream_create_helper_;
16292 }
16293
[email protected]e86839fd2013-08-14 18:29:0316294 // Create a new FakeStream and pass it to the request's
16295 // delegate. Returns a weak pointer to the FakeStream.
16296 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1916297 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0316298 // Do this before calling OnStreamReady() as OnStreamReady() may
16299 // immediately delete |fake_stream|.
16300 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0016301 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0316302 return weak_stream;
16303 }
16304
asanka681f02d2017-02-22 17:06:3916305 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4716306 ADD_FAILURE();
16307 return ERR_UNEXPECTED;
16308 }
16309
dchengb03027d2014-10-21 12:00:2016310 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4716311 ADD_FAILURE();
16312 return LoadState();
16313 }
16314
dchengb03027d2014-10-21 12:00:2016315 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4716316
bnc94c92842016-09-21 15:22:5216317 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716318
bnc6227b26e2016-08-12 02:00:4316319 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4716320
dchengb03027d2014-10-21 12:00:2016321 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716322
ttuttle1f2d7e92015-04-28 16:17:4716323 const ConnectionAttempts& connection_attempts() const override {
16324 static ConnectionAttempts no_attempts;
16325 return no_attempts;
16326 }
16327
[email protected]bf828982013-08-14 18:01:4716328 private:
16329 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0316330 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4416331 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4716332
16333 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
16334};
16335
16336// Fake HttpStreamFactory that vends FakeStreamRequests.
16337class FakeStreamFactory : public HttpStreamFactory {
16338 public:
Chris Watkins7a41d3552017-12-01 02:13:2716339 FakeStreamFactory() = default;
16340 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4716341
16342 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
16343 // RequestStream() (which may be NULL if it was destroyed already).
16344 base::WeakPtr<FakeStreamRequest> last_stream_request() {
16345 return last_stream_request_;
16346 }
16347
xunjieli96f2a402017-06-05 17:24:2716348 std::unique_ptr<HttpStreamRequest> RequestStream(
16349 const HttpRequestInfo& info,
16350 RequestPriority priority,
16351 const SSLConfig& server_ssl_config,
16352 const SSLConfig& proxy_ssl_config,
16353 HttpStreamRequest::Delegate* delegate,
16354 bool enable_ip_based_pooling,
16355 bool enable_alternative_services,
16356 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1916357 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4716358 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716359 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716360 }
16361
xunjieli96f2a402017-06-05 17:24:2716362 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0816363 const HttpRequestInfo& info,
16364 RequestPriority priority,
16365 const SSLConfig& server_ssl_config,
16366 const SSLConfig& proxy_ssl_config,
16367 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2916368 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616369 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016370 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0816371 NOTREACHED();
16372 return nullptr;
16373 }
16374
xunjieli96f2a402017-06-05 17:24:2716375 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4716376 const HttpRequestInfo& info,
16377 RequestPriority priority,
16378 const SSLConfig& server_ssl_config,
16379 const SSLConfig& proxy_ssl_config,
16380 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4616381 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2916382 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616383 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016384 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2716385 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1916386 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4416387 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716388 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716389 }
16390
dchengb03027d2014-10-21 12:00:2016391 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5916392 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4716393 ADD_FAILURE();
16394 }
16395
dchengb03027d2014-10-21 12:00:2016396 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4716397 ADD_FAILURE();
16398 return NULL;
16399 }
16400
xunjielif5267de2017-01-20 21:18:5716401 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
16402 const std::string& parent_absolute_name) const override {
16403 ADD_FAILURE();
16404 }
16405
[email protected]bf828982013-08-14 18:01:4716406 private:
16407 base::WeakPtr<FakeStreamRequest> last_stream_request_;
16408
16409 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16410};
16411
[email protected]bf828982013-08-14 18:01:4716412} // namespace
16413
16414// Make sure that HttpNetworkTransaction passes on its priority to its
16415// stream request on start.
bncd16676a2016-07-20 16:23:0116416TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216418 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716419 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916420 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716421
krasinc06a72a2016-12-21 03:42:4616422 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116423 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716424
Ramin Halavatib5e433e2018-02-07 07:41:1016425 request.traffic_annotation =
16426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16427
wezca1070932016-05-26 20:30:5216428 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716429
[email protected]bf828982013-08-14 18:01:4716430 TestCompletionCallback callback;
16431 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016432 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716433
16434 base::WeakPtr<FakeStreamRequest> fake_request =
16435 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216436 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716437 EXPECT_EQ(LOW, fake_request->priority());
16438}
16439
16440// Make sure that HttpNetworkTransaction passes on its priority
16441// updates to its stream request.
bncd16676a2016-07-20 16:23:0116442TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216444 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716445 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916446 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716447
krasinc06a72a2016-12-21 03:42:4616448 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116449 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716450
Ramin Halavatib5e433e2018-02-07 07:41:1016451 request.traffic_annotation =
16452 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16453
[email protected]bf828982013-08-14 18:01:4716454 TestCompletionCallback callback;
16455 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016456 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716457
16458 base::WeakPtr<FakeStreamRequest> fake_request =
16459 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216460 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716461 EXPECT_EQ(LOW, fake_request->priority());
16462
16463 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216464 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716465 EXPECT_EQ(LOWEST, fake_request->priority());
16466}
16467
[email protected]e86839fd2013-08-14 18:29:0316468// Make sure that HttpNetworkTransaction passes on its priority
16469// updates to its stream.
bncd16676a2016-07-20 16:23:0116470TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
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]e86839fd2013-08-14 18:29:0316473 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916474 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316475
krasinc06a72a2016-12-21 03:42:4616476 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116477 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316478
Ramin Halavatib5e433e2018-02-07 07:41:1016479 request.traffic_annotation =
16480 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16481
[email protected]e86839fd2013-08-14 18:29:0316482 TestCompletionCallback callback;
16483 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016484 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316485
16486 base::WeakPtr<FakeStreamRequest> fake_request =
16487 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216488 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316489 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216490 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316491 EXPECT_EQ(LOW, fake_stream->priority());
16492
16493 trans.SetPriority(LOWEST);
16494 EXPECT_EQ(LOWEST, fake_stream->priority());
16495}
16496
[email protected]043b68c82013-08-22 23:41:5216497// Tests that when a used socket is returned to the SSL socket pool, it's closed
16498// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116499TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216500 ClientSocketPoolManager::set_max_sockets_per_group(
16501 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16502 ClientSocketPoolManager::set_max_sockets_per_pool(
16503 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16504
16505 // Set up SSL request.
16506
16507 HttpRequestInfo ssl_request;
16508 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316509 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016510 ssl_request.traffic_annotation =
16511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216512
16513 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316514 MockWrite(
16515 "GET / HTTP/1.1\r\n"
16516 "Host: www.example.org\r\n"
16517 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216518 };
16519 MockRead ssl_reads[] = {
16520 MockRead("HTTP/1.1 200 OK\r\n"),
16521 MockRead("Content-Length: 11\r\n\r\n"),
16522 MockRead("hello world"),
16523 MockRead(SYNCHRONOUS, OK),
16524 };
16525 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16526 ssl_writes, arraysize(ssl_writes));
16527 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16528
16529 SSLSocketDataProvider ssl(ASYNC, OK);
16530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16531
16532 // Set up HTTP request.
16533
16534 HttpRequestInfo http_request;
16535 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316536 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016537 http_request.traffic_annotation =
16538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216539
16540 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316541 MockWrite(
16542 "GET / HTTP/1.1\r\n"
16543 "Host: www.example.org\r\n"
16544 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216545 };
16546 MockRead http_reads[] = {
16547 MockRead("HTTP/1.1 200 OK\r\n"),
16548 MockRead("Content-Length: 7\r\n\r\n"),
16549 MockRead("falafel"),
16550 MockRead(SYNCHRONOUS, OK),
16551 };
16552 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16553 http_writes, arraysize(http_writes));
16554 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16555
danakj1fd259a02016-04-16 03:17:0916556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216557
16558 // Start the SSL request.
16559 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616560 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016561 ASSERT_EQ(ERR_IO_PENDING,
16562 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16563 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216564
16565 // Start the HTTP request. Pool should stall.
16566 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616567 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016568 ASSERT_EQ(ERR_IO_PENDING,
16569 http_trans.Start(&http_request, http_callback.callback(),
16570 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116571 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216572
16573 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116574 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216575 std::string response_data;
bnc691fda62016-08-12 00:43:1616576 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216577 EXPECT_EQ("hello world", response_data);
16578
16579 // The SSL socket should automatically be closed, so the HTTP request can
16580 // start.
dcheng48459ac22014-08-26 00:46:4116581 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16582 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216583
16584 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116585 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616586 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216587 EXPECT_EQ("falafel", response_data);
16588
dcheng48459ac22014-08-26 00:46:4116589 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216590}
16591
16592// Tests that when a SSL connection is established but there's no corresponding
16593// request that needs it, the new socket is closed if the transport socket pool
16594// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116595TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216596 ClientSocketPoolManager::set_max_sockets_per_group(
16597 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16598 ClientSocketPoolManager::set_max_sockets_per_pool(
16599 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16600
16601 // Set up an ssl request.
16602
16603 HttpRequestInfo ssl_request;
16604 ssl_request.method = "GET";
16605 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1016606 ssl_request.traffic_annotation =
16607 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216608
16609 // No data will be sent on the SSL socket.
16610 StaticSocketDataProvider ssl_data;
16611 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16612
16613 SSLSocketDataProvider ssl(ASYNC, OK);
16614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16615
16616 // Set up HTTP request.
16617
16618 HttpRequestInfo http_request;
16619 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316620 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016621 http_request.traffic_annotation =
16622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216623
16624 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316625 MockWrite(
16626 "GET / HTTP/1.1\r\n"
16627 "Host: www.example.org\r\n"
16628 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216629 };
16630 MockRead http_reads[] = {
16631 MockRead("HTTP/1.1 200 OK\r\n"),
16632 MockRead("Content-Length: 7\r\n\r\n"),
16633 MockRead("falafel"),
16634 MockRead(SYNCHRONOUS, OK),
16635 };
16636 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16637 http_writes, arraysize(http_writes));
16638 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16639
danakj1fd259a02016-04-16 03:17:0916640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216641
16642 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16643 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916644 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916645 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116646 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216647
16648 // Start the HTTP request. Pool should stall.
16649 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616650 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016651 ASSERT_EQ(ERR_IO_PENDING,
16652 http_trans.Start(&http_request, http_callback.callback(),
16653 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116654 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216655
16656 // The SSL connection will automatically be closed once the connection is
16657 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116658 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216659 std::string response_data;
bnc691fda62016-08-12 00:43:1616660 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216661 EXPECT_EQ("falafel", response_data);
16662
dcheng48459ac22014-08-26 00:46:4116663 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216664}
16665
bncd16676a2016-07-20 16:23:0116666TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916667 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216668 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916669 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216670 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416671
16672 HttpRequestInfo request;
16673 request.method = "POST";
16674 request.url = GURL("http://www.foo.com/");
16675 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016676 request.traffic_annotation =
16677 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416678
danakj1fd259a02016-04-16 03:17:0916679 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416681 // Send headers successfully, but get an error while sending the body.
16682 MockWrite data_writes[] = {
16683 MockWrite("POST / HTTP/1.1\r\n"
16684 "Host: www.foo.com\r\n"
16685 "Connection: keep-alive\r\n"
16686 "Content-Length: 3\r\n\r\n"),
16687 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16688 };
16689
16690 MockRead data_reads[] = {
16691 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16692 MockRead("hello world"),
16693 MockRead(SYNCHRONOUS, OK),
16694 };
16695 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16696 arraysize(data_writes));
16697 session_deps_.socket_factory->AddSocketDataProvider(&data);
16698
16699 TestCompletionCallback callback;
16700
tfarina42834112016-09-22 13:38:2016701 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116702 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416703
16704 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116705 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416706
bnc691fda62016-08-12 00:43:1616707 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216708 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416709
wezca1070932016-05-26 20:30:5216710 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416711 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16712
16713 std::string response_data;
bnc691fda62016-08-12 00:43:1616714 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116715 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416716 EXPECT_EQ("hello world", response_data);
16717}
16718
16719// This test makes sure the retry logic doesn't trigger when reading an error
16720// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116721TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416722 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416724 MockWrite data_writes[] = {
16725 MockWrite("GET / HTTP/1.1\r\n"
16726 "Host: www.foo.com\r\n"
16727 "Connection: keep-alive\r\n\r\n"),
16728 MockWrite("POST / HTTP/1.1\r\n"
16729 "Host: www.foo.com\r\n"
16730 "Connection: keep-alive\r\n"
16731 "Content-Length: 3\r\n\r\n"),
16732 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16733 };
16734
16735 MockRead data_reads[] = {
16736 MockRead("HTTP/1.1 200 Peachy\r\n"
16737 "Content-Length: 14\r\n\r\n"),
16738 MockRead("first response"),
16739 MockRead("HTTP/1.1 400 Not OK\r\n"
16740 "Content-Length: 15\r\n\r\n"),
16741 MockRead("second response"),
16742 MockRead(SYNCHRONOUS, OK),
16743 };
16744 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16745 arraysize(data_writes));
16746 session_deps_.socket_factory->AddSocketDataProvider(&data);
16747
16748 TestCompletionCallback callback;
16749 HttpRequestInfo request1;
16750 request1.method = "GET";
16751 request1.url = GURL("http://www.foo.com/");
16752 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016753 request1.traffic_annotation =
16754 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416755
bnc87dcefc2017-05-25 12:47:5816756 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916757 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016758 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416760
16761 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116762 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416763
16764 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216765 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416766
wezca1070932016-05-26 20:30:5216767 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416768 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16769
16770 std::string response_data1;
16771 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116772 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416773 EXPECT_EQ("first response", response_data1);
16774 // Delete the transaction to release the socket back into the socket pool.
16775 trans1.reset();
16776
danakj1fd259a02016-04-16 03:17:0916777 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216778 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916779 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216780 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416781
16782 HttpRequestInfo request2;
16783 request2.method = "POST";
16784 request2.url = GURL("http://www.foo.com/");
16785 request2.upload_data_stream = &upload_data_stream;
16786 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016787 request2.traffic_annotation =
16788 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416789
bnc691fda62016-08-12 00:43:1616790 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016791 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416793
16794 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116795 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416796
bnc691fda62016-08-12 00:43:1616797 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216798 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416799
wezca1070932016-05-26 20:30:5216800 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416801 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16802
16803 std::string response_data2;
bnc691fda62016-08-12 00:43:1616804 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116805 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416806 EXPECT_EQ("second response", response_data2);
16807}
16808
bncd16676a2016-07-20 16:23:0116809TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416810 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916811 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216812 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916813 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216814 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416815
16816 HttpRequestInfo request;
16817 request.method = "POST";
16818 request.url = GURL("http://www.foo.com/");
16819 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016820 request.traffic_annotation =
16821 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416822
danakj1fd259a02016-04-16 03:17:0916823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416825 // Send headers successfully, but get an error while sending the body.
16826 MockWrite data_writes[] = {
16827 MockWrite("POST / HTTP/1.1\r\n"
16828 "Host: www.foo.com\r\n"
16829 "Connection: keep-alive\r\n"
16830 "Content-Length: 3\r\n\r\n"
16831 "fo"),
16832 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16833 };
16834
16835 MockRead data_reads[] = {
16836 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16837 MockRead("hello world"),
16838 MockRead(SYNCHRONOUS, OK),
16839 };
16840 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16841 arraysize(data_writes));
16842 session_deps_.socket_factory->AddSocketDataProvider(&data);
16843
16844 TestCompletionCallback callback;
16845
tfarina42834112016-09-22 13:38:2016846 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416848
16849 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116850 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416851
bnc691fda62016-08-12 00:43:1616852 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216853 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416854
wezca1070932016-05-26 20:30:5216855 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416856 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16857
16858 std::string response_data;
bnc691fda62016-08-12 00:43:1616859 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116860 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416861 EXPECT_EQ("hello world", response_data);
16862}
16863
16864// This tests the more common case than the previous test, where headers and
16865// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116866TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716867 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416868
16869 HttpRequestInfo request;
16870 request.method = "POST";
16871 request.url = GURL("http://www.foo.com/");
16872 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016873 request.traffic_annotation =
16874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416875
danakj1fd259a02016-04-16 03:17:0916876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416878 // Send headers successfully, but get an error while sending the body.
16879 MockWrite data_writes[] = {
16880 MockWrite("POST / HTTP/1.1\r\n"
16881 "Host: www.foo.com\r\n"
16882 "Connection: keep-alive\r\n"
16883 "Transfer-Encoding: chunked\r\n\r\n"),
16884 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16885 };
16886
16887 MockRead data_reads[] = {
16888 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16889 MockRead("hello world"),
16890 MockRead(SYNCHRONOUS, OK),
16891 };
16892 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16893 arraysize(data_writes));
16894 session_deps_.socket_factory->AddSocketDataProvider(&data);
16895
16896 TestCompletionCallback callback;
16897
tfarina42834112016-09-22 13:38:2016898 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416900 // Make sure the headers are sent before adding a chunk. This ensures that
16901 // they can't be merged with the body in a single send. Not currently
16902 // necessary since a chunked body is never merged with headers, but this makes
16903 // the test more future proof.
16904 base::RunLoop().RunUntilIdle();
16905
mmenkecbc2b712014-10-09 20:29:0716906 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416907
16908 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116909 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416910
bnc691fda62016-08-12 00:43:1616911 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216912 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416913
wezca1070932016-05-26 20:30:5216914 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416915 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16916
16917 std::string response_data;
bnc691fda62016-08-12 00:43:1616918 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116919 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416920 EXPECT_EQ("hello world", response_data);
16921}
16922
bncd16676a2016-07-20 16:23:0116923TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916924 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216925 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916926 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216927 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416928
16929 HttpRequestInfo request;
16930 request.method = "POST";
16931 request.url = GURL("http://www.foo.com/");
16932 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016933 request.traffic_annotation =
16934 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416935
danakj1fd259a02016-04-16 03:17:0916936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416938
16939 MockWrite data_writes[] = {
16940 MockWrite("POST / HTTP/1.1\r\n"
16941 "Host: www.foo.com\r\n"
16942 "Connection: keep-alive\r\n"
16943 "Content-Length: 3\r\n\r\n"),
16944 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16945 };
16946
16947 MockRead data_reads[] = {
16948 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16949 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16950 MockRead("hello world"),
16951 MockRead(SYNCHRONOUS, OK),
16952 };
16953 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16954 arraysize(data_writes));
16955 session_deps_.socket_factory->AddSocketDataProvider(&data);
16956
16957 TestCompletionCallback callback;
16958
tfarina42834112016-09-22 13:38:2016959 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116960 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416961
16962 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116963 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416964
bnc691fda62016-08-12 00:43:1616965 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216966 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416967
wezca1070932016-05-26 20:30:5216968 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416969 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16970
16971 std::string response_data;
bnc691fda62016-08-12 00:43:1616972 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116973 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416974 EXPECT_EQ("hello world", response_data);
16975}
16976
bncd16676a2016-07-20 16:23:0116977TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916978 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216979 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916980 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216981 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416982
16983 HttpRequestInfo request;
16984 request.method = "POST";
16985 request.url = GURL("http://www.foo.com/");
16986 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016987 request.traffic_annotation =
16988 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416989
danakj1fd259a02016-04-16 03:17:0916990 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616991 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416992 // Send headers successfully, but get an error while sending the body.
16993 MockWrite data_writes[] = {
16994 MockWrite("POST / HTTP/1.1\r\n"
16995 "Host: www.foo.com\r\n"
16996 "Connection: keep-alive\r\n"
16997 "Content-Length: 3\r\n\r\n"),
16998 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16999 };
17000
17001 MockRead data_reads[] = {
17002 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17003 MockRead("hello world"),
17004 MockRead(SYNCHRONOUS, OK),
17005 };
17006 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17007 arraysize(data_writes));
17008 session_deps_.socket_factory->AddSocketDataProvider(&data);
17009
17010 TestCompletionCallback callback;
17011
tfarina42834112016-09-22 13:38:2017012 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417014
17015 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117016 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417017}
17018
bncd16676a2016-07-20 16:23:0117019TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417020 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917021 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217022 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917023 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217024 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417025
17026 HttpRequestInfo request;
17027 request.method = "POST";
17028 request.url = GURL("http://www.foo.com/");
17029 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017030 request.traffic_annotation =
17031 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417032
danakj1fd259a02016-04-16 03:17:0917033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417035 // Send headers successfully, but get an error while sending the body.
17036 MockWrite data_writes[] = {
17037 MockWrite("POST / HTTP/1.1\r\n"
17038 "Host: www.foo.com\r\n"
17039 "Connection: keep-alive\r\n"
17040 "Content-Length: 3\r\n\r\n"),
17041 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17042 };
17043
17044 MockRead data_reads[] = {
17045 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17046 MockRead("HTTP/1.0 302 Redirect\r\n"),
17047 MockRead("Location: http://somewhere-else.com/\r\n"),
17048 MockRead("Content-Length: 0\r\n\r\n"),
17049 MockRead(SYNCHRONOUS, OK),
17050 };
17051 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17052 arraysize(data_writes));
17053 session_deps_.socket_factory->AddSocketDataProvider(&data);
17054
17055 TestCompletionCallback callback;
17056
tfarina42834112016-09-22 13:38:2017057 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417059
17060 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117061 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417062}
17063
bncd16676a2016-07-20 16:23:0117064TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917065 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217066 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917067 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217068 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417069
17070 HttpRequestInfo request;
17071 request.method = "POST";
17072 request.url = GURL("http://www.foo.com/");
17073 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017074 request.traffic_annotation =
17075 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417076
danakj1fd259a02016-04-16 03:17:0917077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417079 // Send headers successfully, but get an error while sending the body.
17080 MockWrite data_writes[] = {
17081 MockWrite("POST / HTTP/1.1\r\n"
17082 "Host: www.foo.com\r\n"
17083 "Connection: keep-alive\r\n"
17084 "Content-Length: 3\r\n\r\n"),
17085 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17086 };
17087
17088 MockRead data_reads[] = {
17089 MockRead("HTTP 0.9 rocks!"),
17090 MockRead(SYNCHRONOUS, OK),
17091 };
17092 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17093 arraysize(data_writes));
17094 session_deps_.socket_factory->AddSocketDataProvider(&data);
17095
17096 TestCompletionCallback callback;
17097
tfarina42834112016-09-22 13:38:2017098 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417100
17101 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117102 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417103}
17104
bncd16676a2016-07-20 16:23:0117105TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917106 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217107 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917108 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217109 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417110
17111 HttpRequestInfo request;
17112 request.method = "POST";
17113 request.url = GURL("http://www.foo.com/");
17114 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017115 request.traffic_annotation =
17116 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417117
danakj1fd259a02016-04-16 03:17:0917118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417120 // Send headers successfully, but get an error while sending the body.
17121 MockWrite data_writes[] = {
17122 MockWrite("POST / HTTP/1.1\r\n"
17123 "Host: www.foo.com\r\n"
17124 "Connection: keep-alive\r\n"
17125 "Content-Length: 3\r\n\r\n"),
17126 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17127 };
17128
17129 MockRead data_reads[] = {
17130 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17131 MockRead(SYNCHRONOUS, OK),
17132 };
17133 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17134 arraysize(data_writes));
17135 session_deps_.socket_factory->AddSocketDataProvider(&data);
17136
17137 TestCompletionCallback callback;
17138
tfarina42834112016-09-22 13:38:2017139 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417141
17142 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117143 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417144}
17145
Bence Békydca6bd92018-01-30 13:43:0617146#if BUILDFLAG(ENABLE_WEBSOCKETS)
17147
17148namespace {
17149
17150void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17151 headers->SetHeader("Connection", "Upgrade");
17152 headers->SetHeader("Upgrade", "websocket");
17153 headers->SetHeader("Origin", "http://www.example.org");
17154 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617155}
17156
17157} // namespace
17158
17159TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
17160 // The same logic needs to be tested for both ws: and wss: schemes, but this
17161 // test is already parameterised on NextProto, so it uses a loop to verify
17162 // that the different schemes work.
17163 std::string test_cases[] = {"ws://www.example.org/",
17164 "wss://www.example.org/"};
17165 for (size_t i = 0; i < arraysize(test_cases); ++i) {
17166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17167 HttpNetworkSessionPeer peer(session.get());
17168 FakeStreamFactory* fake_factory = new FakeStreamFactory();
17169 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
17170
17171 HttpRequestInfo request;
17172 request.method = "GET";
17173 request.url = GURL(test_cases[i]);
Ramin Halavatib5e433e2018-02-07 07:41:1017174 request.traffic_annotation =
17175 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617176
Bence Béky8d1c6052018-02-07 12:48:1517177 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17178
Bence Békydca6bd92018-01-30 13:43:0617179 HttpNetworkTransaction trans(LOW, session.get());
17180 trans.SetWebSocketHandshakeStreamCreateHelper(
17181 &websocket_stream_create_helper);
17182
17183 TestCompletionCallback callback;
17184 EXPECT_EQ(ERR_IO_PENDING,
17185 trans.Start(&request, callback.callback(), NetLogWithSource()));
17186
17187 base::WeakPtr<FakeStreamRequest> fake_request =
17188 fake_factory->last_stream_request();
17189 ASSERT_TRUE(fake_request);
17190 EXPECT_EQ(&websocket_stream_create_helper,
17191 fake_request->websocket_stream_create_helper());
17192 }
17193}
17194
Adam Rice425cf122015-01-19 06:18:2417195// Verify that proxy headers are not sent to the destination server when
17196// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117197TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417198 HttpRequestInfo request;
17199 request.method = "GET";
bncce36dca22015-04-21 22:11:2317200 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017201 request.traffic_annotation =
17202 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417203 AddWebSocketHeaders(&request.extra_headers);
17204
17205 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917206 session_deps_.proxy_resolution_service =
17207 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2417208
danakj1fd259a02016-04-16 03:17:0917209 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417210
17211 // Since a proxy is configured, try to establish a tunnel.
17212 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717213 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17214 "Host: www.example.org:443\r\n"
17215 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417216
17217 // After calling trans->RestartWithAuth(), this is the request we should
17218 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717219 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17220 "Host: www.example.org:443\r\n"
17221 "Proxy-Connection: keep-alive\r\n"
17222 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417223
rsleevidb16bb02015-11-12 23:47:1717224 MockWrite("GET / HTTP/1.1\r\n"
17225 "Host: www.example.org\r\n"
17226 "Connection: Upgrade\r\n"
17227 "Upgrade: websocket\r\n"
17228 "Origin: http://www.example.org\r\n"
17229 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517230 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17231 "Sec-WebSocket-Extensions: permessage-deflate; "
17232 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417233
17234 // The proxy responds to the connect with a 407, using a persistent
17235 // connection.
17236 MockRead data_reads[] = {
17237 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517238 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17239 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17240 "Content-Length: 0\r\n"
17241 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417242
17243 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17244
Bence Béky8d1c6052018-02-07 12:48:1517245 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17246 "Upgrade: websocket\r\n"
17247 "Connection: Upgrade\r\n"
17248 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417249
17250 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17251 arraysize(data_writes));
17252 session_deps_.socket_factory->AddSocketDataProvider(&data);
17253 SSLSocketDataProvider ssl(ASYNC, OK);
17254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17255
Bence Béky8d1c6052018-02-07 12:48:1517256 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17257
bnc87dcefc2017-05-25 12:47:5817258 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917259 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417260 trans->SetWebSocketHandshakeStreamCreateHelper(
17261 &websocket_stream_create_helper);
17262
17263 {
17264 TestCompletionCallback callback;
17265
tfarina42834112016-09-22 13:38:2017266 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417268
17269 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117270 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417271 }
17272
17273 const HttpResponseInfo* response = trans->GetResponseInfo();
17274 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217275 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417276 EXPECT_EQ(407, response->headers->response_code());
17277
17278 {
17279 TestCompletionCallback callback;
17280
17281 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17282 callback.callback());
robpercival214763f2016-07-01 23:27:0117283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417284
17285 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117286 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417287 }
17288
17289 response = trans->GetResponseInfo();
17290 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217291 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417292
17293 EXPECT_EQ(101, response->headers->response_code());
17294
17295 trans.reset();
17296 session->CloseAllConnections();
17297}
17298
17299// Verify that proxy headers are not sent to the destination server when
17300// establishing a tunnel for an insecure WebSocket connection.
17301// This requires the authentication info to be injected into the auth cache
17302// due to crbug.com/395064
17303// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117304TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417305 HttpRequestInfo request;
17306 request.method = "GET";
bncce36dca22015-04-21 22:11:2317307 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017308 request.traffic_annotation =
17309 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417310 AddWebSocketHeaders(&request.extra_headers);
17311
17312 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917313 session_deps_.proxy_resolution_service =
17314 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2417315
danakj1fd259a02016-04-16 03:17:0917316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417317
17318 MockWrite data_writes[] = {
17319 // Try to establish a tunnel for the WebSocket connection, with
17320 // credentials. Because WebSockets have a separate set of socket pools,
17321 // they cannot and will not use the same TCP/IP connection as the
17322 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517323 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17324 "Host: www.example.org:80\r\n"
17325 "Proxy-Connection: keep-alive\r\n"
17326 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417327
Bence Béky8d1c6052018-02-07 12:48:1517328 MockWrite("GET / HTTP/1.1\r\n"
17329 "Host: www.example.org\r\n"
17330 "Connection: Upgrade\r\n"
17331 "Upgrade: websocket\r\n"
17332 "Origin: http://www.example.org\r\n"
17333 "Sec-WebSocket-Version: 13\r\n"
17334 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17335 "Sec-WebSocket-Extensions: permessage-deflate; "
17336 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417337
17338 MockRead data_reads[] = {
17339 // HTTP CONNECT with credentials.
17340 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17341
17342 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517343 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17344 "Upgrade: websocket\r\n"
17345 "Connection: Upgrade\r\n"
17346 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417347
17348 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17349 arraysize(data_writes));
17350 session_deps_.socket_factory->AddSocketDataProvider(&data);
17351
17352 session->http_auth_cache()->Add(
17353 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17354 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17355
Bence Béky8d1c6052018-02-07 12:48:1517356 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17357
bnc87dcefc2017-05-25 12:47:5817358 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917359 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417360 trans->SetWebSocketHandshakeStreamCreateHelper(
17361 &websocket_stream_create_helper);
17362
17363 TestCompletionCallback callback;
17364
tfarina42834112016-09-22 13:38:2017365 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417367
17368 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117369 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417370
17371 const HttpResponseInfo* response = trans->GetResponseInfo();
17372 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217373 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417374
17375 EXPECT_EQ(101, response->headers->response_code());
17376
17377 trans.reset();
17378 session->CloseAllConnections();
17379}
17380
Bence Békydca6bd92018-01-30 13:43:0617381#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17382
bncd16676a2016-07-20 16:23:0117383TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917384 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217385 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917386 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217387 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217388
17389 HttpRequestInfo request;
17390 request.method = "POST";
17391 request.url = GURL("http://www.foo.com/");
17392 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017393 request.traffic_annotation =
17394 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217395
danakj1fd259a02016-04-16 03:17:0917396 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617397 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217398 MockWrite data_writes[] = {
17399 MockWrite("POST / HTTP/1.1\r\n"
17400 "Host: www.foo.com\r\n"
17401 "Connection: keep-alive\r\n"
17402 "Content-Length: 3\r\n\r\n"),
17403 MockWrite("foo"),
17404 };
17405
17406 MockRead data_reads[] = {
17407 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17408 MockRead(SYNCHRONOUS, OK),
17409 };
17410 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17411 arraysize(data_writes));
17412 session_deps_.socket_factory->AddSocketDataProvider(&data);
17413
17414 TestCompletionCallback callback;
17415
17416 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017417 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117418 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217419
17420 std::string response_data;
bnc691fda62016-08-12 00:43:1617421 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217422
17423 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617424 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217425 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617426 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217427}
17428
bncd16676a2016-07-20 16:23:0117429TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917430 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217431 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917432 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217433 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217434
17435 HttpRequestInfo request;
17436 request.method = "POST";
17437 request.url = GURL("http://www.foo.com/");
17438 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017439 request.traffic_annotation =
17440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217441
danakj1fd259a02016-04-16 03:17:0917442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217444 MockWrite data_writes[] = {
17445 MockWrite("POST / HTTP/1.1\r\n"
17446 "Host: www.foo.com\r\n"
17447 "Connection: keep-alive\r\n"
17448 "Content-Length: 3\r\n\r\n"),
17449 MockWrite("foo"),
17450 };
17451
17452 MockRead data_reads[] = {
17453 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17454 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17455 MockRead(SYNCHRONOUS, OK),
17456 };
17457 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17458 arraysize(data_writes));
17459 session_deps_.socket_factory->AddSocketDataProvider(&data);
17460
17461 TestCompletionCallback callback;
17462
17463 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017464 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117465 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217466
17467 std::string response_data;
bnc691fda62016-08-12 00:43:1617468 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217469
17470 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617471 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217472 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617473 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217474}
17475
bncd16676a2016-07-20 16:23:0117476TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217477 ChunkedUploadDataStream upload_data_stream(0);
17478
17479 HttpRequestInfo request;
17480 request.method = "POST";
17481 request.url = GURL("http://www.foo.com/");
17482 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017483 request.traffic_annotation =
17484 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217485
danakj1fd259a02016-04-16 03:17:0917486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617487 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217488 // Send headers successfully, but get an error while sending the body.
17489 MockWrite data_writes[] = {
17490 MockWrite("POST / HTTP/1.1\r\n"
17491 "Host: www.foo.com\r\n"
17492 "Connection: keep-alive\r\n"
17493 "Transfer-Encoding: chunked\r\n\r\n"),
17494 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17495 };
17496
17497 MockRead data_reads[] = {
17498 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17499 MockRead(SYNCHRONOUS, OK),
17500 };
17501 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17502 arraysize(data_writes));
17503 session_deps_.socket_factory->AddSocketDataProvider(&data);
17504
17505 TestCompletionCallback callback;
17506
17507 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017508 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217509
17510 base::RunLoop().RunUntilIdle();
17511 upload_data_stream.AppendData("f", 1, false);
17512
17513 base::RunLoop().RunUntilIdle();
17514 upload_data_stream.AppendData("oo", 2, true);
17515
robpercival214763f2016-07-01 23:27:0117516 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217517
17518 std::string response_data;
bnc691fda62016-08-12 00:43:1617519 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217520
17521 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617522 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217523 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617524 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217525}
17526
rdsmith1d343be52016-10-21 20:37:5017527// Confirm that transactions whose throttle is created in (and stays in)
17528// the unthrottled state are not blocked.
17529TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17530 TestNetworkStreamThrottler* throttler(nullptr);
17531 std::unique_ptr<HttpNetworkSession> session(
17532 CreateSessionWithThrottler(&session_deps_, &throttler));
17533
17534 // Send a simple request and make sure it goes through.
17535 HttpRequestInfo request;
17536 request.method = "GET";
17537 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017538 request.traffic_annotation =
17539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017540
bnc87dcefc2017-05-25 12:47:5817541 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917542 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017543
17544 MockWrite data_writes[] = {
17545 MockWrite("GET / HTTP/1.1\r\n"
17546 "Host: www.example.org\r\n"
17547 "Connection: keep-alive\r\n\r\n"),
17548 };
17549 MockRead data_reads[] = {
17550 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17551 MockRead(SYNCHRONOUS, OK),
17552 };
17553 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17554 arraysize(data_writes));
17555 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17556
17557 TestCompletionCallback callback;
17558 trans->Start(&request, callback.callback(), NetLogWithSource());
17559 EXPECT_EQ(OK, callback.WaitForResult());
17560}
17561
17562// Confirm requests can be blocked by a throttler, and are resumed
17563// when the throttle is unblocked.
17564TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17565 TestNetworkStreamThrottler* throttler(nullptr);
17566 std::unique_ptr<HttpNetworkSession> session(
17567 CreateSessionWithThrottler(&session_deps_, &throttler));
17568
17569 // Send a simple request and make sure it goes through.
17570 HttpRequestInfo request;
17571 request.method = "GET";
17572 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017573 request.traffic_annotation =
17574 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017575
17576 MockWrite data_writes[] = {
17577 MockWrite("GET / HTTP/1.1\r\n"
17578 "Host: www.example.org\r\n"
17579 "Connection: keep-alive\r\n\r\n"),
17580 };
17581 MockRead data_reads[] = {
17582 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17583 MockRead(SYNCHRONOUS, OK),
17584 };
17585 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17586 arraysize(data_writes));
17587 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17588
17589 // Start a request that will be throttled at start; confirm it
17590 // doesn't complete.
17591 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817592 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917593 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017594
17595 TestCompletionCallback callback;
17596 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17597 EXPECT_EQ(ERR_IO_PENDING, rv);
17598
17599 base::RunLoop().RunUntilIdle();
17600 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17601 EXPECT_FALSE(callback.have_result());
17602
17603 // Confirm the request goes on to complete when unthrottled.
17604 throttler->UnthrottleAllRequests();
17605 base::RunLoop().RunUntilIdle();
17606 ASSERT_TRUE(callback.have_result());
17607 EXPECT_EQ(OK, callback.WaitForResult());
17608}
17609
17610// Destroy a request while it's throttled.
17611TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17612 TestNetworkStreamThrottler* throttler(nullptr);
17613 std::unique_ptr<HttpNetworkSession> session(
17614 CreateSessionWithThrottler(&session_deps_, &throttler));
17615
17616 // Send a simple request and make sure it goes through.
17617 HttpRequestInfo request;
17618 request.method = "GET";
17619 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017620 request.traffic_annotation =
17621 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017622
17623 MockWrite data_writes[] = {
17624 MockWrite("GET / HTTP/1.1\r\n"
17625 "Host: www.example.org\r\n"
17626 "Connection: keep-alive\r\n\r\n"),
17627 };
17628 MockRead data_reads[] = {
17629 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17630 MockRead(SYNCHRONOUS, OK),
17631 };
17632 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17633 arraysize(data_writes));
17634 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17635
17636 // Start a request that will be throttled at start; confirm it
17637 // doesn't complete.
17638 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817639 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917640 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017641
17642 TestCompletionCallback callback;
17643 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17644 EXPECT_EQ(ERR_IO_PENDING, rv);
17645
17646 base::RunLoop().RunUntilIdle();
17647 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17648 EXPECT_FALSE(callback.have_result());
17649
17650 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17651 trans.reset();
17652 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17653}
17654
17655// Confirm the throttler receives SetPriority calls.
17656TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17657 TestNetworkStreamThrottler* throttler(nullptr);
17658 std::unique_ptr<HttpNetworkSession> session(
17659 CreateSessionWithThrottler(&session_deps_, &throttler));
17660
17661 // Send a simple request and make sure it goes through.
17662 HttpRequestInfo request;
17663 request.method = "GET";
17664 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017665 request.traffic_annotation =
17666 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017667
17668 MockWrite data_writes[] = {
17669 MockWrite("GET / HTTP/1.1\r\n"
17670 "Host: www.example.org\r\n"
17671 "Connection: keep-alive\r\n\r\n"),
17672 };
17673 MockRead data_reads[] = {
17674 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17675 MockRead(SYNCHRONOUS, OK),
17676 };
17677 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17678 arraysize(data_writes));
17679 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17680
17681 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917682 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017683 // Start the transaction to associate a throttle with it.
17684 TestCompletionCallback callback;
17685 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17686 EXPECT_EQ(ERR_IO_PENDING, rv);
17687
17688 EXPECT_EQ(0, throttler->num_set_priority_calls());
17689 trans->SetPriority(LOW);
17690 EXPECT_EQ(1, throttler->num_set_priority_calls());
17691 EXPECT_EQ(LOW, throttler->last_priority_set());
17692
17693 throttler->UnthrottleAllRequests();
17694 base::RunLoop().RunUntilIdle();
17695 ASSERT_TRUE(callback.have_result());
17696 EXPECT_EQ(OK, callback.WaitForResult());
17697}
17698
17699// Confirm that unthrottling from a SetPriority call by the
17700// throttler works properly.
17701TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17702 TestNetworkStreamThrottler* throttler(nullptr);
17703 std::unique_ptr<HttpNetworkSession> session(
17704 CreateSessionWithThrottler(&session_deps_, &throttler));
17705
17706 // Send a simple request and make sure it goes through.
17707 HttpRequestInfo request;
17708 request.method = "GET";
17709 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017710 request.traffic_annotation =
17711 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017712
17713 MockWrite data_writes[] = {
17714 MockWrite("GET / HTTP/1.1\r\n"
17715 "Host: www.example.org\r\n"
17716 "Connection: keep-alive\r\n\r\n"),
17717 };
17718 MockRead data_reads[] = {
17719 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17720 MockRead(SYNCHRONOUS, OK),
17721 };
17722 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17723 arraysize(data_writes));
17724 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17725
17726 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17727 data_writes, arraysize(data_writes));
17728 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17729
17730 // Start a request that will be throttled at start; confirm it
17731 // doesn't complete.
17732 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817733 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917734 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017735
17736 TestCompletionCallback callback;
17737 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17738 EXPECT_EQ(ERR_IO_PENDING, rv);
17739
17740 base::RunLoop().RunUntilIdle();
17741 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17742 EXPECT_FALSE(callback.have_result());
17743
17744 // Create a new request, call SetPriority on it to unthrottle,
17745 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917746 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017747 throttler->set_priority_change_closure(
17748 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17749 base::Unretained(throttler)));
17750
17751 // Start the transaction to associate a throttle with it.
17752 TestCompletionCallback callback1;
17753 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17754 EXPECT_EQ(ERR_IO_PENDING, rv);
17755
17756 trans1->SetPriority(IDLE);
17757
17758 base::RunLoop().RunUntilIdle();
17759 ASSERT_TRUE(callback.have_result());
17760 EXPECT_EQ(OK, callback.WaitForResult());
17761 ASSERT_TRUE(callback1.have_result());
17762 EXPECT_EQ(OK, callback1.WaitForResult());
17763}
17764
17765// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817766void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017767
17768// Confirm that destroying a transaction from a SetPriority call by the
17769// throttler works properly.
17770TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17771 TestNetworkStreamThrottler* throttler(nullptr);
17772 std::unique_ptr<HttpNetworkSession> session(
17773 CreateSessionWithThrottler(&session_deps_, &throttler));
17774
17775 // Send a simple request and make sure it goes through.
17776 HttpRequestInfo request;
17777 request.method = "GET";
17778 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017779 request.traffic_annotation =
17780 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017781
17782 MockWrite data_writes[] = {
17783 MockWrite("GET / HTTP/1.1\r\n"
17784 "Host: www.example.org\r\n"
17785 "Connection: keep-alive\r\n\r\n"),
17786 };
17787 MockRead data_reads[] = {
17788 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17789 MockRead(SYNCHRONOUS, OK),
17790 };
17791 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17792 arraysize(data_writes));
17793 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17794
17795 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17796 data_writes, arraysize(data_writes));
17797 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17798
17799 // Start a request that will be throttled at start; confirm it
17800 // doesn't complete.
17801 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817802 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917803 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017804
17805 TestCompletionCallback callback;
17806 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17807 EXPECT_EQ(ERR_IO_PENDING, rv);
17808
17809 base::RunLoop().RunUntilIdle();
17810 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17811 EXPECT_FALSE(callback.have_result());
17812
17813 // Arrange for the set priority call on the above transaction to delete
17814 // the transaction.
bnc87dcefc2017-05-25 12:47:5817815 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017816 throttler->set_priority_change_closure(
17817 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17818
17819 // Call it and check results (partially a "doesn't crash" test).
17820 trans_ptr->SetPriority(IDLE);
17821 trans_ptr = nullptr; // No longer a valid pointer.
17822
17823 base::RunLoop().RunUntilIdle();
17824 ASSERT_FALSE(callback.have_result());
17825}
17826
nharperb7441ef2016-01-25 23:54:1417827#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117828TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417829 const std::string https_url = "https://www.example.com";
17830 HttpRequestInfo request;
17831 request.url = GURL(https_url);
17832 request.method = "GET";
Ramin Halavatib5e433e2018-02-07 07:41:1017833 request.traffic_annotation =
17834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417835
17836 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917837 ssl.ssl_info.token_binding_negotiated = true;
17838 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617839 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417840 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17841
bnc42331402016-07-25 13:36:1517842 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117843 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17844 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417845 MockRead(ASYNC, ERR_IO_PENDING)};
17846 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17847 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817848 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917849 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417851
17852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17853 TestCompletionCallback callback;
17854 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017855 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017856
17857 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417858
17859 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17860 HttpRequestHeaders headers;
17861 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17862 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17863}
17864#endif // !defined(OS_IOS)
17865
eustasc7d27da2017-04-06 10:33:2017866void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17867 const std::string& accept_encoding,
17868 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317869 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017870 bool should_match) {
17871 HttpRequestInfo request;
17872 request.method = "GET";
17873 request.url = GURL("http://www.foo.com/");
17874 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17875 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017876 request.traffic_annotation =
17877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017878
17879 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17881 // Send headers successfully, but get an error while sending the body.
17882 MockWrite data_writes[] = {
17883 MockWrite("GET / HTTP/1.1\r\n"
17884 "Host: www.foo.com\r\n"
17885 "Connection: keep-alive\r\n"
17886 "Accept-Encoding: "),
17887 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17888 };
17889
sky50576f32017-05-01 19:28:0317890 std::string response_code = "200 OK";
17891 std::string extra;
17892 if (!location.empty()) {
17893 response_code = "301 Redirect\r\nLocation: ";
17894 response_code.append(location);
17895 }
17896
eustasc7d27da2017-04-06 10:33:2017897 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317898 MockRead("HTTP/1.0 "),
17899 MockRead(response_code.data()),
17900 MockRead("\r\nContent-Encoding: "),
17901 MockRead(content_encoding.data()),
17902 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017903 MockRead(SYNCHRONOUS, OK),
17904 };
17905 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17906 arraysize(data_writes));
17907 session_deps->socket_factory->AddSocketDataProvider(&data);
17908
17909 TestCompletionCallback callback;
17910
17911 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17913
17914 rv = callback.WaitForResult();
17915 if (should_match) {
17916 EXPECT_THAT(rv, IsOk());
17917 } else {
17918 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17919 }
17920}
17921
17922TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317923 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017924}
17925
17926TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317927 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17928 true);
eustasc7d27da2017-04-06 10:33:2017929}
17930
17931TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17932 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317933 "", false);
17934}
17935
17936TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17937 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17938 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017939}
17940
xunjieli96f2a402017-06-05 17:24:2717941TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17942 ProxyConfig proxy_config;
17943 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17944 proxy_config.set_pac_mandatory(true);
17945 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917946 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Jeremy Roman0579ed62017-08-29 15:56:1917947 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417948 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717949
17950 HttpRequestInfo request;
17951 request.method = "GET";
17952 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017953 request.traffic_annotation =
17954 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717955
17956 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17958
17959 TestCompletionCallback callback;
17960
17961 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17963 EXPECT_THAT(callback.WaitForResult(),
17964 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17965}
17966
17967TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17968 ProxyConfig proxy_config;
17969 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17970 proxy_config.set_pac_mandatory(true);
17971 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17972 new MockAsyncProxyResolverFactory(false);
17973 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917974 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
17975 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
17976 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717977 HttpRequestInfo request;
17978 request.method = "GET";
17979 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017980 request.traffic_annotation =
17981 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717982
17983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17985
17986 TestCompletionCallback callback;
17987 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17989
17990 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17991 ERR_FAILED, &resolver);
17992 EXPECT_THAT(callback.WaitForResult(),
17993 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17994}
17995
17996TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917997 session_deps_.proxy_resolution_service =
17998 ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
xunjieli96f2a402017-06-05 17:24:2717999 session_deps_.enable_quic = false;
18000 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18001
18002 HttpRequestInfo request;
18003 request.method = "GET";
18004 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018005 request.traffic_annotation =
18006 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718007
18008 TestCompletionCallback callback;
18009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18010 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18011 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18012
18013 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18014}
18015
[email protected]89ceba9a2009-03-21 03:46:0618016} // namespace net