blob: 6cc8169a595bdabd7196fab22ba7fdcb923b854e [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4622#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
Bence Békyd74f4382018-02-20 18:26:1926#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4727#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0528#include "base/strings/utf_string_conversions.h"
fdorayf33fede2017-05-11 21:18:1029#include "base/test/scoped_task_environment.h"
[email protected]f36a8132011-09-02 18:36:3330#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3531#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3532#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0733#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3334#include "net/base/completion_callback.h"
Bence Békya25e3f72018-02-13 21:13:3935#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0736#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2537#include "net/base/load_timing_info.h"
38#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2439#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5040#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1541#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3143#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5244#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1545#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0646#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2147#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0848#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1149#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1650#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5351#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2452#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1253#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0054#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2955#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1956#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5757#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5258#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5659#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2460#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1361#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5362#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5763#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3864#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1965#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0766#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0067#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1968#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5169#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4670#include "net/log/test_net_log_entry.h"
71#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4072#include "net/proxy_resolution/mock_proxy_resolver.h"
73#include "net/proxy_resolution/proxy_config_service_fixed.h"
74#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0375#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4076#include "net/proxy_resolution/proxy_resolver.h"
77#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1579#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0380#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4781#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0282#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0783#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0484#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4485#include "net/socket/socket_test_util.h"
86#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0687#include "net/spdy/chromium/spdy_session.h"
88#include "net/spdy/chromium/spdy_session_pool.h"
89#include "net/spdy/chromium/spdy_test_util_common.h"
90#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1491#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5792#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0393#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5794#include "net/ssl/ssl_config_service_defaults.h"
95#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5496#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1197#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0198#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1099#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:43100#include "net/test/test_data_directory.h"
[email protected]baee31a2018-01-18 06:10:23101#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44102#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06103#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18104#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52105#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15106#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27107#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52108
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37109#if defined(NTLM_PORTABLE)
110#include "base/base64.h"
111#include "net/ntlm/ntlm_test_data.h"
112#endif
113
robpercival214763f2016-07-01 23:27:01114using net::test::IsError;
115using net::test::IsOk;
116
[email protected]ad65a3e2013-12-25 18:18:01117using base::ASCIIToUTF16;
118
initial.commit586acc5fe2008-07-26 22:42:52119//-----------------------------------------------------------------------------
120
ttuttle859dc7a2015-04-23 19:42:29121namespace net {
122
[email protected]13c8a092010-07-29 06:15:44123namespace {
124
rdsmith1d343be52016-10-21 20:37:50125class TestNetworkStreamThrottler : public NetworkThrottleManager {
126 public:
127 TestNetworkStreamThrottler()
128 : throttle_new_requests_(false),
129 num_set_priority_calls_(0),
130 last_priority_set_(IDLE) {}
131
132 ~TestNetworkStreamThrottler() override {
133 EXPECT_TRUE(outstanding_throttles_.empty());
134 }
135
136 // NetworkThrottleManager
137 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
138 RequestPriority priority,
139 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58140 auto test_throttle =
Jeremy Roman0579ed62017-08-29 15:56:19141 std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50142 outstanding_throttles_.insert(test_throttle.get());
143 return std::move(test_throttle);
144 }
145
146 void UnthrottleAllRequests() {
147 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25148 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24149 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50150 throttle->Unthrottle();
151 }
152 }
153
154 void set_throttle_new_requests(bool throttle_new_requests) {
155 throttle_new_requests_ = throttle_new_requests;
156 }
157
158 // Includes both throttled and unthrottled throttles.
159 size_t num_outstanding_requests() const {
160 return outstanding_throttles_.size();
161 }
162
163 int num_set_priority_calls() const { return num_set_priority_calls_; }
164 RequestPriority last_priority_set() const { return last_priority_set_; }
165 void set_priority_change_closure(
166 const base::Closure& priority_change_closure) {
167 priority_change_closure_ = priority_change_closure;
168 }
169
170 private:
171 class TestThrottle : public NetworkThrottleManager::Throttle {
172 public:
173 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
174
175 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24176 bool IsBlocked() const override { return throttled_; }
177 RequestPriority Priority() const override {
178 NOTREACHED();
179 return IDLE;
180 }
rdsmith1d343be52016-10-21 20:37:50181 void SetPriority(RequestPriority priority) override {
182 throttler_->SetPriorityCalled(priority);
183 }
184
185 TestThrottle(bool throttled,
186 ThrottleDelegate* delegate,
187 TestNetworkStreamThrottler* throttler)
188 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
189
190 void Unthrottle() {
191 EXPECT_TRUE(throttled_);
192
193 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24194 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50195 }
196
197 bool throttled_;
198 ThrottleDelegate* delegate_;
199 TestNetworkStreamThrottler* throttler_;
200 };
201
202 void OnThrottleDestroyed(TestThrottle* throttle) {
203 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
204 outstanding_throttles_.erase(throttle);
205 }
206
207 void SetPriorityCalled(RequestPriority priority) {
208 ++num_set_priority_calls_;
209 last_priority_set_ = priority;
210 if (!priority_change_closure_.is_null())
211 priority_change_closure_.Run();
212 }
213
214 // Includes both throttled and unthrottled throttles.
215 std::set<TestThrottle*> outstanding_throttles_;
216 bool throttle_new_requests_;
217 int num_set_priority_calls_;
218 RequestPriority last_priority_set_;
219 base::Closure priority_change_closure_;
220
221 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
222};
223
[email protected]42cba2fb2013-03-29 19:58:57224const base::string16 kBar(ASCIIToUTF16("bar"));
225const base::string16 kBar2(ASCIIToUTF16("bar2"));
226const base::string16 kBar3(ASCIIToUTF16("bar3"));
227const base::string16 kBaz(ASCIIToUTF16("baz"));
228const base::string16 kFirst(ASCIIToUTF16("first"));
229const base::string16 kFoo(ASCIIToUTF16("foo"));
230const base::string16 kFoo2(ASCIIToUTF16("foo2"));
231const base::string16 kFoo3(ASCIIToUTF16("foo3"));
232const base::string16 kFou(ASCIIToUTF16("fou"));
233const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57234const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44235
bnc2df4b522016-07-08 18:17:43236const char kAlternativeServiceHttpHeader[] =
237 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
238
ttuttle859dc7a2015-04-23 19:42:29239int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
240 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
241 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02242}
243
ttuttle859dc7a2015-04-23 19:42:29244int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
245 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
246 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02247}
248
ttuttle859dc7a2015-04-23 19:42:29249bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
250 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
251 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52252}
253
[email protected]f3da152d2012-06-02 01:00:57254// Takes in a Value created from a NetLogHttpResponseParameter, and returns
255// a JSONified list of headers as a single string. Uses single quotes instead
256// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27257bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57258 if (!params)
259 return false;
[email protected]ea5ef4c2013-06-13 22:50:27260 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57261 if (!params->GetList("headers", &header_list))
262 return false;
263 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34264 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28265 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57266 return true;
267}
268
[email protected]029c83b62013-01-24 05:28:20269// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
270// used.
ttuttle859dc7a2015-04-23 19:42:29271void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20272 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19273 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25274
[email protected]029c83b62013-01-24 05:28:20275 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
276 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
277
ttuttle859dc7a2015-04-23 19:42:29278 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20279 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25280
281 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25282
[email protected]3b23a222013-05-15 21:33:25283 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25284 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
285 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25286 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25287}
288
[email protected]029c83b62013-01-24 05:28:20289// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
290// used.
ttuttle859dc7a2015-04-23 19:42:29291void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25292 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20293 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19294 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20295
296 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
297 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
298
ttuttle859dc7a2015-04-23 19:42:29299 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
300 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20301 EXPECT_LE(load_timing_info.connect_timing.connect_end,
302 load_timing_info.send_start);
303
304 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20305
[email protected]3b23a222013-05-15 21:33:25306 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20307 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
308 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25309 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20310}
311
312// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
313// used.
ttuttle859dc7a2015-04-23 19:42:29314void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20315 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19316 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20317
ttuttle859dc7a2015-04-23 19:42:29318 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20319
320 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
321 EXPECT_LE(load_timing_info.proxy_resolve_start,
322 load_timing_info.proxy_resolve_end);
323 EXPECT_LE(load_timing_info.proxy_resolve_end,
324 load_timing_info.send_start);
325 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20326
[email protected]3b23a222013-05-15 21:33:25327 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20328 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
329 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25330 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20331}
332
333// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
334// used.
ttuttle859dc7a2015-04-23 19:42:29335void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20336 int connect_timing_flags) {
337 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19338 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20339
340 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
341 EXPECT_LE(load_timing_info.proxy_resolve_start,
342 load_timing_info.proxy_resolve_end);
343 EXPECT_LE(load_timing_info.proxy_resolve_end,
344 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29345 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
346 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20347 EXPECT_LE(load_timing_info.connect_timing.connect_end,
348 load_timing_info.send_start);
349
350 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20351
[email protected]3b23a222013-05-15 21:33:25352 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20353 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
354 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25355 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25356}
357
danakj1fd259a02016-04-16 03:17:09358std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42359 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34360 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14361}
362
rdsmith1d343be52016-10-21 20:37:50363// Note that the pointer written into |*throttler| will only be valid
364// for the lifetime of the returned HttpNetworkSession.
365std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
366 SpdySessionDependencies* session_deps,
367 TestNetworkStreamThrottler** throttler) {
368 std::unique_ptr<HttpNetworkSession> session(
369 SpdySessionDependencies::SpdyCreateSession(session_deps));
370
Jeremy Roman0579ed62017-08-29 15:56:19371 auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50372 *throttler = owned_throttler.get();
373
374 HttpNetworkSessionPeer peer(session.get());
375 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
376
377 return session;
378}
379
xunjieli96f2a402017-06-05 17:24:27380class FailingProxyResolverFactory : public ProxyResolverFactory {
381 public:
382 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
383
384 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42385 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
386 std::unique_ptr<ProxyResolver>* result,
387 const CompletionCallback& callback,
388 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27389 return ERR_PAC_SCRIPT_FAILED;
390 }
391};
392
[email protected]448d4ca52012-03-04 04:12:23393} // namespace
394
bncd16676a2016-07-20 16:23:01395class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03396 public:
bncd16676a2016-07-20 16:23:01397 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03398 // Important to restore the per-pool limit first, since the pool limit must
399 // always be greater than group limit, and the tests reduce both limits.
400 ClientSocketPoolManager::set_max_sockets_per_pool(
401 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
402 ClientSocketPoolManager::set_max_sockets_per_group(
403 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
404 }
405
[email protected]e3ceb682011-06-28 23:55:46406 protected:
[email protected]23e482282013-06-14 16:08:02407 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15408 : ssl_(ASYNC, OK),
409 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03410 HttpNetworkSession::NORMAL_SOCKET_POOL)),
411 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
412 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28413 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03414 }
[email protected]bb88e1d32013-05-03 23:11:07415
[email protected]e3ceb682011-06-28 23:55:46416 struct SimpleGetHelperResult {
417 int rv;
418 std::string status_line;
419 std::string response_data;
sclittlefb249892015-09-10 21:33:22420 int64_t total_received_bytes;
421 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25422 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47423 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59424 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46425 };
426
dcheng67be2b1f2014-10-27 21:47:29427 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50428 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55429 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54430 }
431
dcheng67be2b1f2014-10-27 21:47:29432 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50433 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55434 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09435 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55436 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09437 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50438 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55439 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09440 }
441
[email protected]202965992011-12-07 23:04:51442 // Either |write_failure| specifies a write failure or |read_failure|
443 // specifies a read failure when using a reused socket. In either case, the
444 // failure should cause the network transaction to resend the request, and the
445 // other argument should be NULL.
446 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
447 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52448
[email protected]a34f61ee2014-03-18 20:59:49449 // Either |write_failure| specifies a write failure or |read_failure|
450 // specifies a read failure when using a reused socket. In either case, the
451 // failure should cause the network transaction to resend the request, and the
452 // other argument should be NULL.
453 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10454 const MockRead* read_failure,
455 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49456
[email protected]5a60c8b2011-10-19 20:14:29457 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
458 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15459 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52460
[email protected]ff007e162009-05-23 09:13:15461 HttpRequestInfo request;
462 request.method = "GET";
bncce36dca22015-04-21 22:11:23463 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10464 request.traffic_annotation =
465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52466
vishal.b62985ca92015-04-17 08:45:51467 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07468 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27471
[email protected]5a60c8b2011-10-19 20:14:29472 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07473 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29474 }
initial.commit586acc5fe2008-07-26 22:42:52475
[email protected]49639fa2011-12-20 23:22:41476 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52477
eroman24bc6a12015-05-06 19:55:48478 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16479 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52481
[email protected]ff007e162009-05-23 09:13:15482 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16483 out.total_received_bytes = trans.GetTotalReceivedBytes();
484 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25485
486 // Even in the failure cases that use this function, connections are always
487 // successfully established before the error.
bnc691fda62016-08-12 00:43:16488 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25489 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
490
[email protected]ff007e162009-05-23 09:13:15491 if (out.rv != OK)
492 return out;
493
bnc691fda62016-08-12 00:43:16494 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50495 // Can't use ASSERT_* inside helper functions like this, so
496 // return an error.
wezca1070932016-05-26 20:30:52497 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50498 out.rv = ERR_UNEXPECTED;
499 return out;
500 }
[email protected]ff007e162009-05-23 09:13:15501 out.status_line = response->headers->GetStatusLine();
502
[email protected]80a09a82012-11-16 17:40:06503 EXPECT_EQ("127.0.0.1", response->socket_address.host());
504 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19505
ttuttled9dbc652015-09-29 20:00:59506 bool got_endpoint =
bnc691fda62016-08-12 00:43:16507 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59508 EXPECT_EQ(got_endpoint,
509 out.remote_endpoint_after_start.address().size() > 0);
510
bnc691fda62016-08-12 00:43:16511 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01512 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40513
mmenke43758e62015-05-04 21:09:46514 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40515 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39516 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00517 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
518 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39519 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00520 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
521 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15522
[email protected]f3da152d2012-06-02 01:00:57523 std::string line;
524 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
525 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
526
[email protected]79e1fd62013-06-20 06:50:04527 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16528 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04529 std::string value;
530 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23531 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04532 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
533 EXPECT_EQ("keep-alive", value);
534
535 std::string response_headers;
536 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23537 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04538 response_headers);
[email protected]3deb9a52010-11-11 00:24:40539
bnc691fda62016-08-12 00:43:16540 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22541 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16542 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22543
bnc691fda62016-08-12 00:43:16544 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47545 return out;
[email protected]ff007e162009-05-23 09:13:15546 }
initial.commit586acc5fe2008-07-26 22:42:52547
[email protected]5a60c8b2011-10-19 20:14:29548 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
549 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22550 MockWrite data_writes[] = {
551 MockWrite("GET / HTTP/1.1\r\n"
552 "Host: www.example.org\r\n"
553 "Connection: keep-alive\r\n\r\n"),
554 };
[email protected]5a60c8b2011-10-19 20:14:29555
sclittlefb249892015-09-10 21:33:22556 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
557 arraysize(data_writes));
558 StaticSocketDataProvider* data[] = {&reads};
559 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
560
561 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
562 out.total_sent_bytes);
563 return out;
[email protected]b8015c42013-12-24 15:18:19564 }
565
bnc032658ba2016-09-26 18:17:15566 void AddSSLSocketData() {
567 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49568 ssl_.ssl_info.cert =
569 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
570 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
572 }
573
[email protected]ff007e162009-05-23 09:13:15574 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
575 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52576
[email protected]ff007e162009-05-23 09:13:15577 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07578
579 void BypassHostCacheOnRefreshHelper(int load_flags);
580
581 void CheckErrorIsPassedBack(int error, IoMode mode);
582
[email protected]4bd46222013-05-14 19:32:23583 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07584 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15585 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03586
587 // Original socket limits. Some tests set these. Safest to always restore
588 // them once each test has been run.
589 int old_max_group_sockets_;
590 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15591};
[email protected]231d5a32008-09-13 00:45:27592
[email protected]448d4ca52012-03-04 04:12:23593namespace {
594
ryansturm49a8cb12016-06-15 16:51:09595class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27596 public:
ryansturm49a8cb12016-06-15 16:51:09597 BeforeHeadersSentHandler()
598 : observed_before_headers_sent_with_proxy_(false),
599 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27600
ryansturm49a8cb12016-06-15 16:51:09601 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
602 HttpRequestHeaders* request_headers) {
603 observed_before_headers_sent_ = true;
604 if (!proxy_info.is_http() && !proxy_info.is_https() &&
605 !proxy_info.is_quic()) {
606 return;
607 }
608 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27609 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
610 }
611
ryansturm49a8cb12016-06-15 16:51:09612 bool observed_before_headers_sent_with_proxy() const {
613 return observed_before_headers_sent_with_proxy_;
614 }
615
616 bool observed_before_headers_sent() const {
617 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27618 }
619
620 std::string observed_proxy_server_uri() const {
621 return observed_proxy_server_uri_;
622 }
623
624 private:
ryansturm49a8cb12016-06-15 16:51:09625 bool observed_before_headers_sent_with_proxy_;
626 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27627 std::string observed_proxy_server_uri_;
628
ryansturm49a8cb12016-06-15 16:51:09629 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27630};
631
[email protected]15a5ccf82008-10-23 19:57:43632// Fill |str| with a long header list that consumes >= |size| bytes.
633void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51634 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19635 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
636 const int sizeof_row = strlen(row);
637 const int num_rows = static_cast<int>(
638 ceil(static_cast<float>(size) / sizeof_row));
639 const int sizeof_data = num_rows * sizeof_row;
640 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43641 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51642
[email protected]4ddaf2502008-10-23 18:26:19643 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43644 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19645}
646
thakis84dff942015-07-28 20:47:38647#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09648uint64_t MockGetMSTime() {
649 // Tue, 23 May 2017 20:13:07 +0000
650 return 131400439870000000;
651}
652
[email protected]385a4672009-03-11 22:21:29653// Alternative functions that eliminate randomness and dependency on the local
654// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37655void MockGenerateRandom(uint8_t* output, size_t n) {
656 // This is set to 0xaa because the client challenge for testing in
657 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
658 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29659}
660
[email protected]fe2bc6a2009-03-23 16:52:20661std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37662 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29663}
thakis84dff942015-07-28 20:47:38664#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29665
[email protected]e60e47a2010-07-14 03:37:18666template<typename ParentPool>
667class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31668 public:
[email protected]9e1bdd32011-02-03 21:48:34669 CaptureGroupNameSocketPool(HostResolver* host_resolver,
670 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18671
[email protected]d80a4322009-08-14 07:07:49672 const std::string last_group_name_received() const {
673 return last_group_name_;
674 }
675
Tarun Bansal162eabe52018-01-20 01:16:39676 bool socket_requested() const { return socket_requested_; }
677
dmichaeld6e570d2014-12-18 22:30:57678 int RequestSocket(const std::string& group_name,
679 const void* socket_params,
680 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54681 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15682 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57683 ClientSocketHandle* handle,
684 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20685 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31686 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39687 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31688 return ERR_IO_PENDING;
689 }
dmichaeld6e570d2014-12-18 22:30:57690 void CancelRequest(const std::string& group_name,
691 ClientSocketHandle* handle) override {}
692 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09693 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57694 int id) override {}
695 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23696 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57697 int IdleSocketCount() const override { return 0; }
698 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31699 return 0;
700 }
dmichaeld6e570d2014-12-18 22:30:57701 LoadState GetLoadState(const std::string& group_name,
702 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31703 return LOAD_STATE_IDLE;
704 }
dmichaeld6e570d2014-12-18 22:30:57705 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26706 return base::TimeDelta();
707 }
[email protected]d80a4322009-08-14 07:07:49708
709 private:
[email protected]04e5be32009-06-26 20:00:31710 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39711 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31712};
713
[email protected]ab739042011-04-07 15:22:28714typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
715CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13716typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
717CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06718typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11719CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18720typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
721CaptureGroupNameSSLSocketPool;
722
rkaplowd90695c2015-03-25 22:12:41723template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18724CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34725 HostResolver* host_resolver,
726 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21727 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18728
hashimoto0d3e4fb2015-01-09 05:02:50729template <>
[email protected]2df19bb2010-08-25 20:13:46730CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21731 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34732 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09733 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46734
[email protected]007b3f82013-04-09 08:46:45735template <>
[email protected]e60e47a2010-07-14 03:37:18736CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21737 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34738 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45739 : SSLClientSocketPool(0,
740 0,
[email protected]007b3f82013-04-09 08:46:45741 cert_verifier,
742 NULL,
743 NULL,
[email protected]284303b62013-11-28 15:11:54744 NULL,
eranm6571b2b2014-12-03 15:53:23745 NULL,
[email protected]007b3f82013-04-09 08:46:45746 std::string(),
747 NULL,
748 NULL,
749 NULL,
750 NULL,
751 NULL,
[email protected]8e458552014-08-05 00:02:15752 NULL) {
753}
[email protected]2227c692010-05-04 15:36:11754
[email protected]231d5a32008-09-13 00:45:27755//-----------------------------------------------------------------------------
756
[email protected]79cb5c12011-09-12 13:12:04757// Helper functions for validating that AuthChallengeInfo's are correctly
758// configured for common cases.
759bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
760 if (!auth_challenge)
761 return false;
762 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43763 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04764 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19765 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04766 return true;
767}
768
769bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
770 if (!auth_challenge)
771 return false;
772 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43773 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
774 EXPECT_EQ("MyRealm1", auth_challenge->realm);
775 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
776 return true;
777}
778
779bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
780 if (!auth_challenge)
781 return false;
782 EXPECT_TRUE(auth_challenge->is_proxy);
783 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04784 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19785 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04786 return true;
787}
788
789bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
790 if (!auth_challenge)
791 return false;
792 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43793 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04794 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19795 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04796 return true;
797}
798
thakis84dff942015-07-28 20:47:38799#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04800bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
801 if (!auth_challenge)
802 return false;
803 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55804 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04805 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19806 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04807 return true;
808}
thakis84dff942015-07-28 20:47:38809#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04810
[email protected]448d4ca52012-03-04 04:12:23811} // namespace
812
bncd16676a2016-07-20 16:23:01813TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27816}
817
bncd16676a2016-07-20 16:23:01818TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27819 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35820 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
821 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06822 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27823 };
[email protected]31a2bfe2010-02-09 08:03:39824 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
825 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01826 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27827 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
828 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22829 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
830 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47831 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59832
833 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27834}
835
836// Response with no status line.
bncd16676a2016-07-20 16:23:01837TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27838 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35839 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06840 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27841 };
[email protected]31a2bfe2010-02-09 08:03:39842 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
843 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41844 EXPECT_THAT(out.rv, IsOk());
845 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
846 EXPECT_EQ("hello world", out.response_data);
847 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
848 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27849}
850
mmenkea7da6da2016-09-01 21:56:52851// Response with no status line, and a weird port. Should fail by default.
852TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
853 MockRead data_reads[] = {
854 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
855 };
856
857 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
858 session_deps_.socket_factory->AddSocketDataProvider(&data);
859
860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
861
krasinc06a72a2016-12-21 03:42:46862 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58863 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19864 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52865
mmenkea7da6da2016-09-01 21:56:52866 request.method = "GET";
867 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10868 request.traffic_annotation =
869 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
870
mmenkea7da6da2016-09-01 21:56:52871 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20872 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52873 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
874}
875
Shivani Sharmafdcaefd2017-11-02 00:12:26876// Tests that request info can be destroyed after the headers phase is complete.
877TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
879 auto trans =
880 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
881
882 MockRead data_reads[] = {
883 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
884 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
885 };
886 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
887 session_deps_.socket_factory->AddSocketDataProvider(&data);
888
889 TestCompletionCallback callback;
890
891 {
892 auto request = std::make_unique<HttpRequestInfo>();
893 request->method = "GET";
894 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10895 request->traffic_annotation =
896 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26897
898 int rv =
899 trans->Start(request.get(), callback.callback(), NetLogWithSource());
900
901 EXPECT_THAT(callback.GetResult(rv), IsOk());
902 } // Let request info be destroyed.
903
904 trans.reset();
905}
906
mmenkea7da6da2016-09-01 21:56:52907// Response with no status line, and a weird port. Option to allow weird ports
908// enabled.
909TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
910 MockRead data_reads[] = {
911 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
912 };
913
914 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
915 session_deps_.socket_factory->AddSocketDataProvider(&data);
916 session_deps_.http_09_on_non_default_ports_enabled = true;
917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
918
krasinc06a72a2016-12-21 03:42:46919 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58920 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19921 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52922
mmenkea7da6da2016-09-01 21:56:52923 request.method = "GET";
924 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10925 request.traffic_annotation =
926 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
927
mmenkea7da6da2016-09-01 21:56:52928 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20929 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52930 EXPECT_THAT(callback.GetResult(rv), IsOk());
931
932 const HttpResponseInfo* info = trans->GetResponseInfo();
933 ASSERT_TRUE(info->headers);
934 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
935
936 // Don't bother to read the body - that's verified elsewhere, important thing
937 // is that the option to allow HTTP/0.9 on non-default ports is respected.
938}
939
[email protected]231d5a32008-09-13 00:45:27940// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01941TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27942 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35943 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06944 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27945 };
[email protected]31a2bfe2010-02-09 08:03:39946 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
947 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01948 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27949 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
950 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22951 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
952 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27953}
954
955// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01956TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27957 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35958 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06959 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27960 };
[email protected]31a2bfe2010-02-09 08:03:39961 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01963 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27964 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
965 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22966 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
967 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27968}
969
970// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01971TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27972 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35973 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06974 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27975 };
[email protected]31a2bfe2010-02-09 08:03:39976 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
977 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41978 EXPECT_THAT(out.rv, IsOk());
979 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
980 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
981 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
982 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27983}
984
985// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01986TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27987 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35988 MockRead("\n"),
989 MockRead("\n"),
990 MockRead("Q"),
991 MockRead("J"),
992 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06993 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27994 };
[email protected]31a2bfe2010-02-09 08:03:39995 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
996 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01997 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27998 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
999 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:221000 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1001 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:271002}
1003
1004// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:011005TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:271006 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351007 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:061008 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:271009 };
[email protected]31a2bfe2010-02-09 08:03:391010 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1011 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411012 EXPECT_THAT(out.rv, IsOk());
1013 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1014 EXPECT_EQ("HTT", out.response_data);
1015 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1016 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521017}
1018
[email protected]f9d44aa2008-09-23 23:57:171019// Simulate a 204 response, lacking a Content-Length header, sent over a
1020// persistent connection. The response should still terminate since a 204
1021// cannot have a response body.
bncd16676a2016-07-20 16:23:011022TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191023 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171024 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351025 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191026 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061027 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171028 };
[email protected]31a2bfe2010-02-09 08:03:391029 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1030 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011031 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171032 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1033 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221034 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1035 int64_t response_size = reads_size - strlen(junk);
1036 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171037}
1038
[email protected]0877e3d2009-10-17 22:29:571039// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011040TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191041 std::string final_chunk = "0\r\n\r\n";
1042 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1043 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571044 MockRead data_reads[] = {
1045 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1046 MockRead("5\r\nHello\r\n"),
1047 MockRead("1\r\n"),
1048 MockRead(" \r\n"),
1049 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191050 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061051 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571052 };
[email protected]31a2bfe2010-02-09 08:03:391053 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1054 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011055 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571056 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1057 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221058 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1059 int64_t response_size = reads_size - extra_data.size();
1060 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571061}
1062
[email protected]9fe44f52010-09-23 18:36:001063// Next tests deal with http://crbug.com/56344.
1064
bncd16676a2016-07-20 16:23:011065TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001066 MultipleContentLengthHeadersNoTransferEncoding) {
1067 MockRead data_reads[] = {
1068 MockRead("HTTP/1.1 200 OK\r\n"),
1069 MockRead("Content-Length: 10\r\n"),
1070 MockRead("Content-Length: 5\r\n\r\n"),
1071 };
1072 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1073 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011074 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001075}
1076
bncd16676a2016-07-20 16:23:011077TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041078 DuplicateContentLengthHeadersNoTransferEncoding) {
1079 MockRead data_reads[] = {
1080 MockRead("HTTP/1.1 200 OK\r\n"),
1081 MockRead("Content-Length: 5\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 MockRead("Hello"),
1084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041088 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1089 EXPECT_EQ("Hello", out.response_data);
1090}
1091
bncd16676a2016-07-20 16:23:011092TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041093 ComplexContentLengthHeadersNoTransferEncoding) {
1094 // More than 2 dupes.
1095 {
1096 MockRead data_reads[] = {
1097 MockRead("HTTP/1.1 200 OK\r\n"),
1098 MockRead("Content-Length: 5\r\n"),
1099 MockRead("Content-Length: 5\r\n"),
1100 MockRead("Content-Length: 5\r\n\r\n"),
1101 MockRead("Hello"),
1102 };
1103 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1104 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011105 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041106 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1107 EXPECT_EQ("Hello", out.response_data);
1108 }
1109 // HTTP/1.0
1110 {
1111 MockRead data_reads[] = {
1112 MockRead("HTTP/1.0 200 OK\r\n"),
1113 MockRead("Content-Length: 5\r\n"),
1114 MockRead("Content-Length: 5\r\n"),
1115 MockRead("Content-Length: 5\r\n\r\n"),
1116 MockRead("Hello"),
1117 };
1118 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1119 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011120 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041121 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1122 EXPECT_EQ("Hello", out.response_data);
1123 }
1124 // 2 dupes and one mismatched.
1125 {
1126 MockRead data_reads[] = {
1127 MockRead("HTTP/1.1 200 OK\r\n"),
1128 MockRead("Content-Length: 10\r\n"),
1129 MockRead("Content-Length: 10\r\n"),
1130 MockRead("Content-Length: 5\r\n\r\n"),
1131 };
1132 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1133 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011134 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041135 }
1136}
1137
bncd16676a2016-07-20 16:23:011138TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001139 MultipleContentLengthHeadersTransferEncoding) {
1140 MockRead data_reads[] = {
1141 MockRead("HTTP/1.1 200 OK\r\n"),
1142 MockRead("Content-Length: 666\r\n"),
1143 MockRead("Content-Length: 1337\r\n"),
1144 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1145 MockRead("5\r\nHello\r\n"),
1146 MockRead("1\r\n"),
1147 MockRead(" \r\n"),
1148 MockRead("5\r\nworld\r\n"),
1149 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061150 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001151 };
1152 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1153 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011154 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001155 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1156 EXPECT_EQ("Hello world", out.response_data);
1157}
1158
[email protected]1628fe92011-10-04 23:04:551159// Next tests deal with http://crbug.com/98895.
1160
1161// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011162TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551163 MockRead data_reads[] = {
1164 MockRead("HTTP/1.1 200 OK\r\n"),
1165 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1166 MockRead("Content-Length: 5\r\n\r\n"),
1167 MockRead("Hello"),
1168 };
1169 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1170 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011171 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551172 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1173 EXPECT_EQ("Hello", out.response_data);
1174}
1175
[email protected]54a9c6e52012-03-21 20:10:591176// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011177TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551178 MockRead data_reads[] = {
1179 MockRead("HTTP/1.1 200 OK\r\n"),
1180 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1181 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1182 MockRead("Content-Length: 5\r\n\r\n"),
1183 MockRead("Hello"),
1184 };
1185 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1186 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011187 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591188 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1189 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551190}
1191
1192// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011193TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551194 MockRead data_reads[] = {
1195 MockRead("HTTP/1.1 200 OK\r\n"),
1196 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1197 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1198 MockRead("Content-Length: 5\r\n\r\n"),
1199 MockRead("Hello"),
1200 };
1201 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1202 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011203 EXPECT_THAT(out.rv,
1204 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551205}
1206
[email protected]54a9c6e52012-03-21 20:10:591207// Checks that two identical Location headers result in no error.
1208// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011209TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551210 MockRead data_reads[] = {
1211 MockRead("HTTP/1.1 302 Redirect\r\n"),
1212 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591213 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551214 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061215 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551216 };
1217
1218 HttpRequestInfo request;
1219 request.method = "GET";
1220 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101221 request.traffic_annotation =
1222 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551223
danakj1fd259a02016-04-16 03:17:091224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551226
1227 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071228 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551229
[email protected]49639fa2011-12-20 23:22:411230 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551231
tfarina42834112016-09-22 13:38:201232 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551234
robpercival214763f2016-07-01 23:27:011235 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551236
bnc691fda62016-08-12 00:43:161237 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521238 ASSERT_TRUE(response);
1239 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551240 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1241 std::string url;
1242 EXPECT_TRUE(response->headers->IsRedirect(&url));
1243 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471244 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551245}
1246
[email protected]1628fe92011-10-04 23:04:551247// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011248TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551249 MockRead data_reads[] = {
1250 MockRead("HTTP/1.1 302 Redirect\r\n"),
1251 MockRead("Location: http://good.com/\r\n"),
1252 MockRead("Location: http://evil.com/\r\n"),
1253 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061254 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551255 };
1256 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1257 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011258 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551259}
1260
[email protected]ef0faf2e72009-03-05 23:27:231261// Do a request using the HEAD method. Verify that we don't try to read the
1262// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011263TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421264 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231265 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231266 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101267 request.traffic_annotation =
1268 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231269
danakj1fd259a02016-04-16 03:17:091270 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161271 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091272 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161273 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091274 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1275 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271276
[email protected]ef0faf2e72009-03-05 23:27:231277 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131278 MockWrite("HEAD / HTTP/1.1\r\n"
1279 "Host: www.example.org\r\n"
1280 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231281 };
1282 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231283 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1284 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231285
mmenked39192ee2015-12-09 00:57:231286 // No response body because the test stops reading here.
1287 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231288 };
1289
[email protected]31a2bfe2010-02-09 08:03:391290 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1291 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071292 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231293
[email protected]49639fa2011-12-20 23:22:411294 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231295
tfarina42834112016-09-22 13:38:201296 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231298
1299 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011300 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231301
bnc691fda62016-08-12 00:43:161302 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521303 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231304
1305 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521306 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231307 EXPECT_EQ(1234, response->headers->GetContentLength());
1308 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471309 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091310 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1311 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231312
1313 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101314 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231315 bool has_server_header = response->headers->EnumerateHeader(
1316 &iter, "Server", &server_header);
1317 EXPECT_TRUE(has_server_header);
1318 EXPECT_EQ("Blah", server_header);
1319
1320 // Reading should give EOF right away, since there is no message body
1321 // (despite non-zero content-length).
1322 std::string response_data;
bnc691fda62016-08-12 00:43:161323 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011324 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231325 EXPECT_EQ("", response_data);
1326}
1327
bncd16676a2016-07-20 16:23:011328TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521330
1331 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351332 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1333 MockRead("hello"),
1334 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1335 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061336 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521337 };
[email protected]31a2bfe2010-02-09 08:03:391338 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071339 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521340
[email protected]0b0bf032010-09-21 18:08:501341 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521342 "hello", "world"
1343 };
1344
1345 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421346 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521347 request.method = "GET";
bncce36dca22015-04-21 22:11:231348 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101349 request.traffic_annotation =
1350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521351
bnc691fda62016-08-12 00:43:161352 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271353
[email protected]49639fa2011-12-20 23:22:411354 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521355
tfarina42834112016-09-22 13:38:201356 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521358
1359 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011360 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521361
bnc691fda62016-08-12 00:43:161362 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521363 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521364
wezca1070932016-05-26 20:30:521365 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251366 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471367 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521368
1369 std::string response_data;
bnc691fda62016-08-12 00:43:161370 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011371 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251372 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521373 }
1374}
1375
bncd16676a2016-07-20 16:23:011376TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091377 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221378 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191379 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221380 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271381
[email protected]1c773ea12009-04-28 19:58:421382 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521383 request.method = "POST";
1384 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271385 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101386 request.traffic_annotation =
1387 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521388
shivanishab9a143952016-09-19 17:23:411389 // Check the upload progress returned before initialization is correct.
1390 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1391 EXPECT_EQ(0u, progress.size());
1392 EXPECT_EQ(0u, progress.position());
1393
danakj1fd259a02016-04-16 03:17:091394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271396
initial.commit586acc5fe2008-07-26 22:42:521397 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351398 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1399 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1400 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061401 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521402 };
[email protected]31a2bfe2010-02-09 08:03:391403 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071404 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521405
[email protected]49639fa2011-12-20 23:22:411406 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521407
tfarina42834112016-09-22 13:38:201408 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521410
1411 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011412 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521413
bnc691fda62016-08-12 00:43:161414 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521415 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521416
wezca1070932016-05-26 20:30:521417 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251418 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521419
1420 std::string response_data;
bnc691fda62016-08-12 00:43:161421 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011422 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251423 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521424}
1425
[email protected]3a2d3662009-03-27 03:49:141426// This test is almost the same as Ignores100 above, but the response contains
1427// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571428// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011429TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421430 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141431 request.method = "GET";
1432 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101433 request.traffic_annotation =
1434 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141435
danakj1fd259a02016-04-16 03:17:091436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271438
[email protected]3a2d3662009-03-27 03:49:141439 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571440 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1441 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141442 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061443 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141444 };
[email protected]31a2bfe2010-02-09 08:03:391445 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071446 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141447
[email protected]49639fa2011-12-20 23:22:411448 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141449
tfarina42834112016-09-22 13:38:201450 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141452
1453 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011454 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141455
bnc691fda62016-08-12 00:43:161456 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521457 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141458
wezca1070932016-05-26 20:30:521459 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141460 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1461
1462 std::string response_data;
bnc691fda62016-08-12 00:43:161463 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011464 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141465 EXPECT_EQ("hello world", response_data);
1466}
1467
bncd16676a2016-07-20 16:23:011468TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081469 HttpRequestInfo request;
1470 request.method = "POST";
1471 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101472 request.traffic_annotation =
1473 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081474
danakj1fd259a02016-04-16 03:17:091475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081477
1478 MockRead data_reads[] = {
1479 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1480 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381481 };
zmo9528c9f42015-08-04 22:12:081482 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1483 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381484
zmo9528c9f42015-08-04 22:12:081485 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381486
tfarina42834112016-09-22 13:38:201487 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381489
zmo9528c9f42015-08-04 22:12:081490 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011491 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381492
zmo9528c9f42015-08-04 22:12:081493 std::string response_data;
bnc691fda62016-08-12 00:43:161494 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011495 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081496 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381497}
1498
bncd16676a2016-07-20 16:23:011499TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381500 HttpRequestInfo request;
1501 request.method = "POST";
1502 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101503 request.traffic_annotation =
1504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381505
danakj1fd259a02016-04-16 03:17:091506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271508
[email protected]ee9410e72010-01-07 01:42:381509 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061510 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381511 };
[email protected]31a2bfe2010-02-09 08:03:391512 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071513 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381514
[email protected]49639fa2011-12-20 23:22:411515 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381516
tfarina42834112016-09-22 13:38:201517 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381519
1520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011521 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381522}
1523
[email protected]23e482282013-06-14 16:08:021524void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511525 const MockWrite* write_failure,
1526 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421527 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521528 request.method = "GET";
1529 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101530 request.traffic_annotation =
1531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521532
vishal.b62985ca92015-04-17 08:45:511533 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071534 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271536
[email protected]202965992011-12-07 23:04:511537 // Written data for successfully sending both requests.
1538 MockWrite data1_writes[] = {
1539 MockWrite("GET / HTTP/1.1\r\n"
1540 "Host: www.foo.com\r\n"
1541 "Connection: keep-alive\r\n\r\n"),
1542 MockWrite("GET / HTTP/1.1\r\n"
1543 "Host: www.foo.com\r\n"
1544 "Connection: keep-alive\r\n\r\n")
1545 };
1546
1547 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521548 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351549 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1550 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061551 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521552 };
[email protected]202965992011-12-07 23:04:511553
1554 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491555 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511556 data1_writes[1] = *write_failure;
1557 } else {
1558 ASSERT_TRUE(read_failure);
1559 data1_reads[2] = *read_failure;
1560 }
1561
1562 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1563 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071564 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521565
1566 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351567 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1568 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061569 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521570 };
[email protected]31a2bfe2010-02-09 08:03:391571 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071572 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521573
thestig9d3bb0c2015-01-24 00:49:511574 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521575 "hello", "world"
1576 };
1577
mikecironef22f9812016-10-04 03:40:191578 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521579 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411580 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521581
bnc691fda62016-08-12 00:43:161582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521583
tfarina42834112016-09-22 13:38:201584 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521586
1587 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011588 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521589
[email protected]58e32bb2013-01-21 18:23:251590 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161591 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251592 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1593 if (i == 0) {
1594 first_socket_log_id = load_timing_info.socket_log_id;
1595 } else {
1596 // The second request should be using a new socket.
1597 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1598 }
1599
bnc691fda62016-08-12 00:43:161600 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521601 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521602
wezca1070932016-05-26 20:30:521603 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471604 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521606
1607 std::string response_data;
bnc691fda62016-08-12 00:43:161608 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011609 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251610 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521611 }
1612}
[email protected]3d2a59b2008-09-26 19:44:251613
[email protected]a34f61ee2014-03-18 20:59:491614void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1615 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101616 const MockRead* read_failure,
1617 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491618 HttpRequestInfo request;
1619 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101620 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101621 request.traffic_annotation =
1622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491623
vishal.b62985ca92015-04-17 08:45:511624 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491625 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491627
[email protected]09356c652014-03-25 15:36:101628 SSLSocketDataProvider ssl1(ASYNC, OK);
1629 SSLSocketDataProvider ssl2(ASYNC, OK);
1630 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361631 ssl1.next_proto = kProtoHTTP2;
1632 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101633 }
1634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1635 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491636
[email protected]09356c652014-03-25 15:36:101637 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411638 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491639 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411640 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151641 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411642 SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191643 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491644
[email protected]09356c652014-03-25 15:36:101645 // HTTP/1.1 versions of the request and response.
1646 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1647 "Host: www.foo.com\r\n"
1648 "Connection: keep-alive\r\n\r\n";
1649 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1650 const char kHttpData[] = "hello";
1651
1652 std::vector<MockRead> data1_reads;
1653 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491654 if (write_failure) {
1655 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101656 data1_writes.push_back(*write_failure);
1657 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491658 } else {
1659 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101660 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411661 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101662 } else {
1663 data1_writes.push_back(MockWrite(kHttpRequest));
1664 }
1665 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491666 }
1667
[email protected]09356c652014-03-25 15:36:101668 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1669 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491670 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1671
[email protected]09356c652014-03-25 15:36:101672 std::vector<MockRead> data2_reads;
1673 std::vector<MockWrite> data2_writes;
1674
1675 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411676 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101677
bncdf80d44fd2016-07-15 20:27:411678 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1679 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101680 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1681 } else {
1682 data2_writes.push_back(
1683 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1684
1685 data2_reads.push_back(
1686 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1687 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1688 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1689 }
rch8e6c6c42015-05-01 14:05:131690 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1691 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491692 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1693
1694 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591695 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491696 // Wait for the preconnect to complete.
1697 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1698 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101699 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491700
1701 // Make the request.
1702 TestCompletionCallback callback;
1703
bnc691fda62016-08-12 00:43:161704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491705
tfarina42834112016-09-22 13:38:201706 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491708
1709 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011710 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491711
1712 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161713 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101714 TestLoadTimingNotReused(
1715 load_timing_info,
1716 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491717
bnc691fda62016-08-12 00:43:161718 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521719 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491720
wezca1070932016-05-26 20:30:521721 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021722 if (response->was_fetched_via_spdy) {
1723 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1724 } else {
1725 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1726 }
[email protected]a34f61ee2014-03-18 20:59:491727
1728 std::string response_data;
bnc691fda62016-08-12 00:43:161729 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011730 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101731 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491732}
1733
Biljith Jayan45a41722017-08-16 18:43:141734// Test that we do not retry indefinitely when a server sends an error like
1735// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1736// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1737TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1738 HttpRequestInfo request;
1739 request.method = "GET";
1740 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101741 request.traffic_annotation =
1742 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141743
1744 // Check whether we give up after the third try.
1745
1746 // Construct an HTTP2 request and a "Go away" response.
1747 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1748 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291749 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141750 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1751 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1752
1753 // Three go away responses.
1754 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1755 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1756 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1757
1758 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1759 AddSSLSocketData();
1760 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1761 AddSSLSocketData();
1762 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1763 AddSSLSocketData();
1764
1765 TestCompletionCallback callback;
1766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1768
1769 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1771
1772 rv = callback.WaitForResult();
1773 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1774}
1775
1776TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1777 HttpRequestInfo request;
1778 request.method = "GET";
1779 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101780 request.traffic_annotation =
1781 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141782
1783 // Check whether we try atleast thrice before giving up.
1784
1785 // Construct an HTTP2 request and a "Go away" response.
1786 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1787 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291788 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141789 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1790 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1791
1792 // Construct a non error HTTP2 response.
1793 SpdySerializedFrame spdy_response_no_error(
1794 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1795 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1796 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1797 CreateMockRead(spdy_data, 2)};
1798
1799 // Two error responses.
1800 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1801 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1802 // Followed by a success response.
1803 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1804
1805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1806 AddSSLSocketData();
1807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1808 AddSSLSocketData();
1809 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1810 AddSSLSocketData();
1811
1812 TestCompletionCallback callback;
1813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1815
1816 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1818
1819 rv = callback.WaitForResult();
1820 EXPECT_THAT(rv, IsOk());
1821}
1822
bncd16676a2016-07-20 16:23:011823TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061824 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511825 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1826}
1827
bncd16676a2016-07-20 16:23:011828TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061829 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511830 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251831}
1832
bncd16676a2016-07-20 16:23:011833TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061834 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511835 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251836}
1837
[email protected]d58ceea82014-06-04 10:55:541838// Make sure that on a 408 response (Request Timeout), the request is retried,
1839// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011840TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541841 MockRead read_failure(SYNCHRONOUS,
1842 "HTTP/1.1 408 Request Timeout\r\n"
1843 "Connection: Keep-Alive\r\n"
1844 "Content-Length: 6\r\n\r\n"
1845 "Pickle");
1846 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1847}
1848
bncd16676a2016-07-20 16:23:011849TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491850 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101851 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491852}
1853
bncd16676a2016-07-20 16:23:011854TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491855 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101856 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491857}
1858
bncd16676a2016-07-20 16:23:011859TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491860 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101861 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1862}
1863
bncd16676a2016-07-20 16:23:011864TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101865 MockRead read_failure(ASYNC, OK); // EOF
1866 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1867}
1868
[email protected]d58ceea82014-06-04 10:55:541869// Make sure that on a 408 response (Request Timeout), the request is retried,
1870// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011871TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541872 MockRead read_failure(SYNCHRONOUS,
1873 "HTTP/1.1 408 Request Timeout\r\n"
1874 "Connection: Keep-Alive\r\n"
1875 "Content-Length: 6\r\n\r\n"
1876 "Pickle");
1877 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1878 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1879}
1880
bncd16676a2016-07-20 16:23:011881TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101882 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1883 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1884}
1885
bncd16676a2016-07-20 16:23:011886TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101887 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1888 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1889}
1890
bncd16676a2016-07-20 16:23:011891TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101892 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1893 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1894}
1895
bncd16676a2016-07-20 16:23:011896TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101897 MockRead read_failure(ASYNC, OK); // EOF
1898 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491899}
1900
bncd16676a2016-07-20 16:23:011901TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421902 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251903 request.method = "GET";
bncce36dca22015-04-21 22:11:231904 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101905 request.traffic_annotation =
1906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251907
danakj1fd259a02016-04-16 03:17:091908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271910
[email protected]3d2a59b2008-09-26 19:44:251911 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061912 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351913 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1914 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061915 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251916 };
[email protected]31a2bfe2010-02-09 08:03:391917 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071918 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251919
[email protected]49639fa2011-12-20 23:22:411920 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251921
tfarina42834112016-09-22 13:38:201922 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251924
1925 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011926 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591927
1928 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161929 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591930 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251931}
1932
1933// What do various browsers do when the server closes a non-keepalive
1934// connection without sending any response header or body?
1935//
1936// IE7: error page
1937// Safari 3.1.2 (Windows): error page
1938// Firefox 3.0.1: blank page
1939// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421940// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1941// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011942TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251943 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061944 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351945 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1946 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061947 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251948 };
[email protected]31a2bfe2010-02-09 08:03:391949 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1950 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011951 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251952}
[email protected]1826a402014-01-08 15:40:481953
[email protected]7a5378b2012-11-04 03:25:171954// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1955// tests. There was a bug causing HttpNetworkTransaction to hang in the
1956// destructor in such situations.
1957// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011958TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171959 HttpRequestInfo request;
1960 request.method = "GET";
bncce36dca22015-04-21 22:11:231961 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101962 request.traffic_annotation =
1963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171964
danakj1fd259a02016-04-16 03:17:091965 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581966 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191967 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171968
1969 MockRead data_reads[] = {
1970 MockRead("HTTP/1.0 200 OK\r\n"),
1971 MockRead("Connection: keep-alive\r\n"),
1972 MockRead("Content-Length: 100\r\n\r\n"),
1973 MockRead("hello"),
1974 MockRead(SYNCHRONOUS, 0),
1975 };
1976 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071977 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171978
1979 TestCompletionCallback callback;
1980
tfarina42834112016-09-22 13:38:201981 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171983
1984 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011985 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171986
1987 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501988 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171989 if (rv == ERR_IO_PENDING)
1990 rv = callback.WaitForResult();
1991 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501992 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011993 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171994
1995 trans.reset();
fdoray92e35a72016-06-10 15:54:551996 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171997 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1998}
1999
bncd16676a2016-07-20 16:23:012000TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172001 HttpRequestInfo request;
2002 request.method = "GET";
bncce36dca22015-04-21 22:11:232003 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102004 request.traffic_annotation =
2005 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172006
danakj1fd259a02016-04-16 03:17:092007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582008 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192009 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172010
2011 MockRead data_reads[] = {
2012 MockRead("HTTP/1.0 200 OK\r\n"),
2013 MockRead("Connection: keep-alive\r\n"),
2014 MockRead("Content-Length: 100\r\n\r\n"),
2015 MockRead(SYNCHRONOUS, 0),
2016 };
2017 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072018 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172019
2020 TestCompletionCallback callback;
2021
tfarina42834112016-09-22 13:38:202022 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172024
2025 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012026 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172027
2028 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:502029 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172030 if (rv == ERR_IO_PENDING)
2031 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012032 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172033
2034 trans.reset();
fdoray92e35a72016-06-10 15:54:552035 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172036 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2037}
2038
[email protected]0b0bf032010-09-21 18:08:502039// Test that we correctly reuse a keep-alive connection after not explicitly
2040// reading the body.
bncd16676a2016-07-20 16:23:012041TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132042 HttpRequestInfo request;
2043 request.method = "GET";
2044 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102045 request.traffic_annotation =
2046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132047
vishal.b62985ca92015-04-17 08:45:512048 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072049 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092050 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272051
mmenkecc2298e2015-12-07 18:20:182052 const char* request_data =
2053 "GET / HTTP/1.1\r\n"
2054 "Host: www.foo.com\r\n"
2055 "Connection: keep-alive\r\n\r\n";
2056 MockWrite data_writes[] = {
2057 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2058 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2059 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2060 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2061 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2062 };
2063
[email protected]0b0bf032010-09-21 18:08:502064 // Note that because all these reads happen in the same
2065 // StaticSocketDataProvider, it shows that the same socket is being reused for
2066 // all transactions.
mmenkecc2298e2015-12-07 18:20:182067 MockRead data_reads[] = {
2068 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2069 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2070 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2071 MockRead(ASYNC, 7,
2072 "HTTP/1.1 302 Found\r\n"
2073 "Content-Length: 0\r\n\r\n"),
2074 MockRead(ASYNC, 9,
2075 "HTTP/1.1 302 Found\r\n"
2076 "Content-Length: 5\r\n\r\n"
2077 "hello"),
2078 MockRead(ASYNC, 11,
2079 "HTTP/1.1 301 Moved Permanently\r\n"
2080 "Content-Length: 0\r\n\r\n"),
2081 MockRead(ASYNC, 13,
2082 "HTTP/1.1 301 Moved Permanently\r\n"
2083 "Content-Length: 5\r\n\r\n"
2084 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132085
mmenkecc2298e2015-12-07 18:20:182086 // In the next two rounds, IsConnectedAndIdle returns false, due to
2087 // the set_busy_before_sync_reads(true) call, while the
2088 // HttpNetworkTransaction is being shut down, but the socket is still
2089 // reuseable. See http://crbug.com/544255.
2090 MockRead(ASYNC, 15,
2091 "HTTP/1.1 200 Hunky-Dory\r\n"
2092 "Content-Length: 5\r\n\r\n"),
2093 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132094
mmenkecc2298e2015-12-07 18:20:182095 MockRead(ASYNC, 18,
2096 "HTTP/1.1 200 Hunky-Dory\r\n"
2097 "Content-Length: 5\r\n\r\n"
2098 "he"),
2099 MockRead(SYNCHRONOUS, 19, "llo"),
2100
2101 // The body of the final request is actually read.
2102 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2103 MockRead(ASYNC, 22, "hello"),
2104 };
2105 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2106 arraysize(data_writes));
2107 data.set_busy_before_sync_reads(true);
2108 session_deps_.socket_factory->AddSocketDataProvider(&data);
2109
2110 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502111 std::string response_lines[kNumUnreadBodies];
2112
mikecironef22f9812016-10-04 03:40:192113 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182114 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412115 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132116
Jeremy Roman0579ed62017-08-29 15:56:192117 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582118 session.get());
[email protected]fc31d6a42010-06-24 18:05:132119
tfarina42834112016-09-22 13:38:202120 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132122
[email protected]58e32bb2013-01-21 18:23:252123 LoadTimingInfo load_timing_info;
2124 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2125 if (i == 0) {
2126 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2127 first_socket_log_id = load_timing_info.socket_log_id;
2128 } else {
2129 TestLoadTimingReused(load_timing_info);
2130 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2131 }
2132
[email protected]fc31d6a42010-06-24 18:05:132133 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182134 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132135
mmenkecc2298e2015-12-07 18:20:182136 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502137 response_lines[i] = response->headers->GetStatusLine();
2138
mmenkecc2298e2015-12-07 18:20:182139 // Delete the transaction without reading the response bodies. Then spin
2140 // the message loop, so the response bodies are drained.
2141 trans.reset();
2142 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132143 }
[email protected]0b0bf032010-09-21 18:08:502144
2145 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182146 "HTTP/1.1 204 No Content",
2147 "HTTP/1.1 205 Reset Content",
2148 "HTTP/1.1 304 Not Modified",
2149 "HTTP/1.1 302 Found",
2150 "HTTP/1.1 302 Found",
2151 "HTTP/1.1 301 Moved Permanently",
2152 "HTTP/1.1 301 Moved Permanently",
2153 "HTTP/1.1 200 Hunky-Dory",
2154 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502155 };
2156
mostynb91e0da982015-01-20 19:17:272157 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2158 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502159
2160 for (int i = 0; i < kNumUnreadBodies; ++i)
2161 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2162
[email protected]49639fa2011-12-20 23:22:412163 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202165 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012166 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162167 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182168 ASSERT_TRUE(response);
2169 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502170 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2171 std::string response_data;
bnc691fda62016-08-12 00:43:162172 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012173 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502174 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132175}
2176
mmenke5f94fda2016-06-02 20:54:132177// Sockets that receive extra data after a response is complete should not be
2178// reused.
bncd16676a2016-07-20 16:23:012179TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2181 MockWrite data_writes1[] = {
2182 MockWrite("HEAD / HTTP/1.1\r\n"
2183 "Host: www.borked.com\r\n"
2184 "Connection: keep-alive\r\n\r\n"),
2185 };
2186
2187 MockRead data_reads1[] = {
2188 MockRead("HTTP/1.1 200 OK\r\n"
2189 "Connection: keep-alive\r\n"
2190 "Content-Length: 22\r\n\r\n"
2191 "This server is borked."),
2192 };
2193
2194 MockWrite data_writes2[] = {
2195 MockWrite("GET /foo HTTP/1.1\r\n"
2196 "Host: www.borked.com\r\n"
2197 "Connection: keep-alive\r\n\r\n"),
2198 };
2199
2200 MockRead data_reads2[] = {
2201 MockRead("HTTP/1.1 200 OK\r\n"
2202 "Content-Length: 3\r\n\r\n"
2203 "foo"),
2204 };
2205 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2206 data_writes1, arraysize(data_writes1));
2207 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2208 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2209 data_writes2, arraysize(data_writes2));
2210 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2211
2212 TestCompletionCallback callback;
2213 HttpRequestInfo request1;
2214 request1.method = "HEAD";
2215 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102216 request1.traffic_annotation =
2217 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132218
bnc87dcefc2017-05-25 12:47:582219 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192220 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202221 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012222 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132223
2224 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2225 ASSERT_TRUE(response1);
2226 ASSERT_TRUE(response1->headers);
2227 EXPECT_EQ(200, response1->headers->response_code());
2228 EXPECT_TRUE(response1->headers->IsKeepAlive());
2229
2230 std::string response_data1;
robpercival214763f2016-07-01 23:27:012231 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132232 EXPECT_EQ("", response_data1);
2233 // Deleting the transaction attempts to release the socket back into the
2234 // socket pool.
2235 trans1.reset();
2236
2237 HttpRequestInfo request2;
2238 request2.method = "GET";
2239 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102240 request2.traffic_annotation =
2241 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132242
bnc87dcefc2017-05-25 12:47:582243 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192244 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202245 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012246 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132247
2248 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2249 ASSERT_TRUE(response2);
2250 ASSERT_TRUE(response2->headers);
2251 EXPECT_EQ(200, response2->headers->response_code());
2252
2253 std::string response_data2;
robpercival214763f2016-07-01 23:27:012254 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132255 EXPECT_EQ("foo", response_data2);
2256}
2257
bncd16676a2016-07-20 16:23:012258TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2260 MockWrite data_writes1[] = {
2261 MockWrite("GET / HTTP/1.1\r\n"
2262 "Host: www.borked.com\r\n"
2263 "Connection: keep-alive\r\n\r\n"),
2264 };
2265
2266 MockRead data_reads1[] = {
2267 MockRead("HTTP/1.1 200 OK\r\n"
2268 "Connection: keep-alive\r\n"
2269 "Content-Length: 22\r\n\r\n"
2270 "This server is borked."
2271 "Bonus data!"),
2272 };
2273
2274 MockWrite data_writes2[] = {
2275 MockWrite("GET /foo HTTP/1.1\r\n"
2276 "Host: www.borked.com\r\n"
2277 "Connection: keep-alive\r\n\r\n"),
2278 };
2279
2280 MockRead data_reads2[] = {
2281 MockRead("HTTP/1.1 200 OK\r\n"
2282 "Content-Length: 3\r\n\r\n"
2283 "foo"),
2284 };
2285 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2286 data_writes1, arraysize(data_writes1));
2287 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2288 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2289 data_writes2, arraysize(data_writes2));
2290 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2291
2292 TestCompletionCallback callback;
2293 HttpRequestInfo request1;
2294 request1.method = "GET";
2295 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102296 request1.traffic_annotation =
2297 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132298
bnc87dcefc2017-05-25 12:47:582299 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192300 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202301 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012302 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132303
2304 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2305 ASSERT_TRUE(response1);
2306 ASSERT_TRUE(response1->headers);
2307 EXPECT_EQ(200, response1->headers->response_code());
2308 EXPECT_TRUE(response1->headers->IsKeepAlive());
2309
2310 std::string response_data1;
robpercival214763f2016-07-01 23:27:012311 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132312 EXPECT_EQ("This server is borked.", response_data1);
2313 // Deleting the transaction attempts to release the socket back into the
2314 // socket pool.
2315 trans1.reset();
2316
2317 HttpRequestInfo request2;
2318 request2.method = "GET";
2319 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102320 request2.traffic_annotation =
2321 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132322
bnc87dcefc2017-05-25 12:47:582323 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192324 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202325 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012326 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132327
2328 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2329 ASSERT_TRUE(response2);
2330 ASSERT_TRUE(response2->headers);
2331 EXPECT_EQ(200, response2->headers->response_code());
2332
2333 std::string response_data2;
robpercival214763f2016-07-01 23:27:012334 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132335 EXPECT_EQ("foo", response_data2);
2336}
2337
bncd16676a2016-07-20 16:23:012338TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2340 MockWrite data_writes1[] = {
2341 MockWrite("GET / HTTP/1.1\r\n"
2342 "Host: www.borked.com\r\n"
2343 "Connection: keep-alive\r\n\r\n"),
2344 };
2345
2346 MockRead data_reads1[] = {
2347 MockRead("HTTP/1.1 200 OK\r\n"
2348 "Connection: keep-alive\r\n"
2349 "Transfer-Encoding: chunked\r\n\r\n"),
2350 MockRead("16\r\nThis server is borked.\r\n"),
2351 MockRead("0\r\n\r\nBonus data!"),
2352 };
2353
2354 MockWrite data_writes2[] = {
2355 MockWrite("GET /foo HTTP/1.1\r\n"
2356 "Host: www.borked.com\r\n"
2357 "Connection: keep-alive\r\n\r\n"),
2358 };
2359
2360 MockRead data_reads2[] = {
2361 MockRead("HTTP/1.1 200 OK\r\n"
2362 "Content-Length: 3\r\n\r\n"
2363 "foo"),
2364 };
2365 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2366 data_writes1, arraysize(data_writes1));
2367 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2368 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2369 data_writes2, arraysize(data_writes2));
2370 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2371
2372 TestCompletionCallback callback;
2373 HttpRequestInfo request1;
2374 request1.method = "GET";
2375 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102376 request1.traffic_annotation =
2377 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132378
bnc87dcefc2017-05-25 12:47:582379 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192380 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202381 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012382 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132383
2384 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2385 ASSERT_TRUE(response1);
2386 ASSERT_TRUE(response1->headers);
2387 EXPECT_EQ(200, response1->headers->response_code());
2388 EXPECT_TRUE(response1->headers->IsKeepAlive());
2389
2390 std::string response_data1;
robpercival214763f2016-07-01 23:27:012391 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132392 EXPECT_EQ("This server is borked.", response_data1);
2393 // Deleting the transaction attempts to release the socket back into the
2394 // socket pool.
2395 trans1.reset();
2396
2397 HttpRequestInfo request2;
2398 request2.method = "GET";
2399 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102400 request2.traffic_annotation =
2401 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132402
bnc87dcefc2017-05-25 12:47:582403 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192404 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202405 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012406 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132407
2408 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2409 ASSERT_TRUE(response2);
2410 ASSERT_TRUE(response2->headers);
2411 EXPECT_EQ(200, response2->headers->response_code());
2412
2413 std::string response_data2;
robpercival214763f2016-07-01 23:27:012414 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132415 EXPECT_EQ("foo", response_data2);
2416}
2417
2418// This is a little different from the others - it tests the case that the
2419// HttpStreamParser doesn't know if there's extra data on a socket or not when
2420// the HttpNetworkTransaction is torn down, because the response body hasn't
2421// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012422TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132423 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2424 MockWrite data_writes1[] = {
2425 MockWrite("GET / HTTP/1.1\r\n"
2426 "Host: www.borked.com\r\n"
2427 "Connection: keep-alive\r\n\r\n"),
2428 };
2429
2430 MockRead data_reads1[] = {
2431 MockRead("HTTP/1.1 200 OK\r\n"
2432 "Connection: keep-alive\r\n"
2433 "Transfer-Encoding: chunked\r\n\r\n"),
2434 MockRead("16\r\nThis server is borked.\r\n"),
2435 MockRead("0\r\n\r\nBonus data!"),
2436 };
2437 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2438 data_writes1, arraysize(data_writes1));
2439 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2440
2441 TestCompletionCallback callback;
2442 HttpRequestInfo request1;
2443 request1.method = "GET";
2444 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102445 request1.traffic_annotation =
2446 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132447
bnc87dcefc2017-05-25 12:47:582448 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192449 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582450 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012451 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132452
bnc87dcefc2017-05-25 12:47:582453 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132454 ASSERT_TRUE(response1);
2455 ASSERT_TRUE(response1->headers);
2456 EXPECT_EQ(200, response1->headers->response_code());
2457 EXPECT_TRUE(response1->headers->IsKeepAlive());
2458
2459 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2460 // response body.
bnc87dcefc2017-05-25 12:47:582461 trans.reset();
mmenke5f94fda2016-06-02 20:54:132462
2463 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2464 // socket can't be reused, rather than returning it to the socket pool.
2465 base::RunLoop().RunUntilIdle();
2466
2467 // There should be no idle sockets in the pool.
2468 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2469}
2470
[email protected]038e9a32008-10-08 22:40:162471// Test the request-challenge-retry sequence for basic auth.
2472// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012473TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422474 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162475 request.method = "GET";
bncce36dca22015-04-21 22:11:232476 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102477 request.traffic_annotation =
2478 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162479
vishal.b62985ca92015-04-17 08:45:512480 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072481 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272484
[email protected]f9ee6b52008-11-08 06:46:232485 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232486 MockWrite(
2487 "GET / HTTP/1.1\r\n"
2488 "Host: www.example.org\r\n"
2489 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232490 };
2491
[email protected]038e9a32008-10-08 22:40:162492 MockRead data_reads1[] = {
2493 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2494 // Give a couple authenticate options (only the middle one is actually
2495 // supported).
[email protected]22927ad2009-09-21 19:56:192496 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162497 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2498 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2499 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2500 // Large content-length -- won't matter, as connection will be reset.
2501 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062502 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162503 };
2504
2505 // After calling trans->RestartWithAuth(), this is the request we should
2506 // be issuing -- the final header line contains the credentials.
2507 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232508 MockWrite(
2509 "GET / HTTP/1.1\r\n"
2510 "Host: www.example.org\r\n"
2511 "Connection: keep-alive\r\n"
2512 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162513 };
2514
2515 // Lastly, the server responds with the actual content.
2516 MockRead data_reads2[] = {
2517 MockRead("HTTP/1.0 200 OK\r\n"),
2518 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2519 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062520 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162521 };
2522
[email protected]31a2bfe2010-02-09 08:03:392523 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2524 data_writes1, arraysize(data_writes1));
2525 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2526 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2528 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162529
[email protected]49639fa2011-12-20 23:22:412530 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162531
tfarina42834112016-09-22 13:38:202532 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162534
2535 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012536 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162537
[email protected]58e32bb2013-01-21 18:23:252538 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162539 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252540 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2541
sclittlefb249892015-09-10 21:33:222542 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162543 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222544 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162545 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192546
bnc691fda62016-08-12 00:43:162547 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522548 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042549 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162550
[email protected]49639fa2011-12-20 23:22:412551 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162552
bnc691fda62016-08-12 00:43:162553 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162555
2556 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012557 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162558
[email protected]58e32bb2013-01-21 18:23:252559 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162560 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252561 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2562 // The load timing after restart should have a new socket ID, and times after
2563 // those of the first load timing.
2564 EXPECT_LE(load_timing_info1.receive_headers_end,
2565 load_timing_info2.connect_timing.connect_start);
2566 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2567
sclittlefb249892015-09-10 21:33:222568 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162569 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222570 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162571 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192572
bnc691fda62016-08-12 00:43:162573 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522574 ASSERT_TRUE(response);
2575 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162576 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162577}
2578
ttuttled9dbc652015-09-29 20:00:592579// Test the request-challenge-retry sequence for basic auth.
2580// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012581TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592582 HttpRequestInfo request;
2583 request.method = "GET";
2584 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102585 request.traffic_annotation =
2586 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592587
2588 TestNetLog log;
2589 MockHostResolver* resolver = new MockHostResolver();
2590 session_deps_.net_log = &log;
2591 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092592 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592594
2595 resolver->rules()->ClearRules();
2596 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2597
2598 MockWrite data_writes1[] = {
2599 MockWrite("GET / HTTP/1.1\r\n"
2600 "Host: www.example.org\r\n"
2601 "Connection: keep-alive\r\n\r\n"),
2602 };
2603
2604 MockRead data_reads1[] = {
2605 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2606 // Give a couple authenticate options (only the middle one is actually
2607 // supported).
2608 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2609 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2610 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2611 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2612 // Large content-length -- won't matter, as connection will be reset.
2613 MockRead("Content-Length: 10000\r\n\r\n"),
2614 MockRead(SYNCHRONOUS, ERR_FAILED),
2615 };
2616
2617 // After calling trans->RestartWithAuth(), this is the request we should
2618 // be issuing -- the final header line contains the credentials.
2619 MockWrite data_writes2[] = {
2620 MockWrite("GET / HTTP/1.1\r\n"
2621 "Host: www.example.org\r\n"
2622 "Connection: keep-alive\r\n"
2623 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2624 };
2625
2626 // Lastly, the server responds with the actual content.
2627 MockRead data_reads2[] = {
2628 MockRead("HTTP/1.0 200 OK\r\n"),
2629 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2630 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2631 };
2632
2633 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2634 data_writes1, arraysize(data_writes1));
2635 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2636 data_writes2, arraysize(data_writes2));
2637 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2638 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2639
2640 TestCompletionCallback callback1;
2641
bnc691fda62016-08-12 00:43:162642 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202643 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592644
2645 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162646 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592647 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2648
2649 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162650 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592651 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162652 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592653
bnc691fda62016-08-12 00:43:162654 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592655 ASSERT_TRUE(response);
2656 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2657
2658 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162659 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592660 ASSERT_FALSE(endpoint.address().empty());
2661 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2662
2663 resolver->rules()->ClearRules();
2664 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2665
2666 TestCompletionCallback callback2;
2667
bnc691fda62016-08-12 00:43:162668 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592669 AuthCredentials(kFoo, kBar), callback2.callback())));
2670
2671 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162672 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592673 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2674 // The load timing after restart should have a new socket ID, and times after
2675 // those of the first load timing.
2676 EXPECT_LE(load_timing_info1.receive_headers_end,
2677 load_timing_info2.connect_timing.connect_start);
2678 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2679
2680 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162681 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592682 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162683 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592684
bnc691fda62016-08-12 00:43:162685 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592686 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522687 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592688 EXPECT_EQ(100, response->headers->GetContentLength());
2689
bnc691fda62016-08-12 00:43:162690 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592691 ASSERT_FALSE(endpoint.address().empty());
2692 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2693}
2694
bncd16676a2016-07-20 16:23:012695TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462696 HttpRequestInfo request;
2697 request.method = "GET";
bncce36dca22015-04-21 22:11:232698 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292699 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102700 request.traffic_annotation =
2701 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462702
danakj1fd259a02016-04-16 03:17:092703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272705
[email protected]861fcd52009-08-26 02:33:462706 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232707 MockWrite(
2708 "GET / HTTP/1.1\r\n"
2709 "Host: www.example.org\r\n"
2710 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462711 };
2712
2713 MockRead data_reads[] = {
2714 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2715 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2716 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2717 // Large content-length -- won't matter, as connection will be reset.
2718 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062719 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462720 };
2721
[email protected]31a2bfe2010-02-09 08:03:392722 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2723 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072724 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412725 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462726
tfarina42834112016-09-22 13:38:202727 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462729
2730 rv = callback.WaitForResult();
2731 EXPECT_EQ(0, rv);
2732
sclittlefb249892015-09-10 21:33:222733 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162734 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222735 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162736 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192737
bnc691fda62016-08-12 00:43:162738 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522739 ASSERT_TRUE(response);
2740 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462741}
2742
[email protected]2d2697f92009-02-18 21:00:322743// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2744// connection.
bncd16676a2016-07-20 16:23:012745TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182746 // On the second pass, the body read of the auth challenge is synchronous, so
2747 // IsConnectedAndIdle returns false. The socket should still be drained and
2748 // reused. See http://crbug.com/544255.
2749 for (int i = 0; i < 2; ++i) {
2750 HttpRequestInfo request;
2751 request.method = "GET";
2752 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102753 request.traffic_annotation =
2754 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322755
mmenkecc2298e2015-12-07 18:20:182756 TestNetLog log;
2757 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272759
mmenkecc2298e2015-12-07 18:20:182760 MockWrite data_writes[] = {
2761 MockWrite(ASYNC, 0,
2762 "GET / HTTP/1.1\r\n"
2763 "Host: www.example.org\r\n"
2764 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322765
bnc691fda62016-08-12 00:43:162766 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182767 // be issuing -- the final header line contains the credentials.
2768 MockWrite(ASYNC, 6,
2769 "GET / HTTP/1.1\r\n"
2770 "Host: www.example.org\r\n"
2771 "Connection: keep-alive\r\n"
2772 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2773 };
[email protected]2d2697f92009-02-18 21:00:322774
mmenkecc2298e2015-12-07 18:20:182775 MockRead data_reads[] = {
2776 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2777 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2778 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2779 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2780 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322781
mmenkecc2298e2015-12-07 18:20:182782 // Lastly, the server responds with the actual content.
2783 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2784 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2785 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2786 MockRead(ASYNC, 10, "Hello"),
2787 };
[email protected]2d2697f92009-02-18 21:00:322788
mmenkecc2298e2015-12-07 18:20:182789 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2790 arraysize(data_writes));
2791 data.set_busy_before_sync_reads(true);
2792 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462793
mmenkecc2298e2015-12-07 18:20:182794 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322795
bnc691fda62016-08-12 00:43:162796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202797 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012798 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322799
mmenkecc2298e2015-12-07 18:20:182800 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162801 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182802 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322803
bnc691fda62016-08-12 00:43:162804 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182805 ASSERT_TRUE(response);
2806 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322807
mmenkecc2298e2015-12-07 18:20:182808 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252809
bnc691fda62016-08-12 00:43:162810 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2811 callback2.callback());
robpercival214763f2016-07-01 23:27:012812 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322813
mmenkecc2298e2015-12-07 18:20:182814 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162815 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182816 TestLoadTimingReused(load_timing_info2);
2817 // The load timing after restart should have the same socket ID, and times
2818 // those of the first load timing.
2819 EXPECT_LE(load_timing_info1.receive_headers_end,
2820 load_timing_info2.send_start);
2821 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322822
bnc691fda62016-08-12 00:43:162823 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182824 ASSERT_TRUE(response);
2825 EXPECT_FALSE(response->auth_challenge);
2826 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322827
mmenkecc2298e2015-12-07 18:20:182828 std::string response_data;
bnc691fda62016-08-12 00:43:162829 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322830
mmenkecc2298e2015-12-07 18:20:182831 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162832 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182833 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162834 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182835 }
[email protected]2d2697f92009-02-18 21:00:322836}
2837
2838// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2839// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012840TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422841 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322842 request.method = "GET";
bncce36dca22015-04-21 22:11:232843 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102844 request.traffic_annotation =
2845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322846
danakj1fd259a02016-04-16 03:17:092847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272848
[email protected]2d2697f92009-02-18 21:00:322849 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162850 MockWrite("GET / HTTP/1.1\r\n"
2851 "Host: www.example.org\r\n"
2852 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322853
bnc691fda62016-08-12 00:43:162854 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232855 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162856 MockWrite("GET / HTTP/1.1\r\n"
2857 "Host: www.example.org\r\n"
2858 "Connection: keep-alive\r\n"
2859 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322860 };
2861
[email protected]2d2697f92009-02-18 21:00:322862 MockRead data_reads1[] = {
2863 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2864 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312865 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322866
2867 // Lastly, the server responds with the actual content.
2868 MockRead("HTTP/1.1 200 OK\r\n"),
2869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502870 MockRead("Content-Length: 5\r\n\r\n"),
2871 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322872 };
2873
[email protected]2d0a4f92011-05-05 16:38:462874 // An incorrect reconnect would cause this to be read.
2875 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062876 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462877 };
2878
[email protected]31a2bfe2010-02-09 08:03:392879 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2880 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462881 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2882 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072883 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2884 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322885
[email protected]49639fa2011-12-20 23:22:412886 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322887
bnc691fda62016-08-12 00:43:162888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202889 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322891
2892 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012893 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322894
bnc691fda62016-08-12 00:43:162895 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522896 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042897 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322898
[email protected]49639fa2011-12-20 23:22:412899 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322900
bnc691fda62016-08-12 00:43:162901 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322903
2904 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012905 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322906
bnc691fda62016-08-12 00:43:162907 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522908 ASSERT_TRUE(response);
2909 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502910 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322911}
2912
2913// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2914// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012915TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422916 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322917 request.method = "GET";
bncce36dca22015-04-21 22:11:232918 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102919 request.traffic_annotation =
2920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322921
danakj1fd259a02016-04-16 03:17:092922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272923
[email protected]2d2697f92009-02-18 21:00:322924 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162925 MockWrite("GET / HTTP/1.1\r\n"
2926 "Host: www.example.org\r\n"
2927 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322928
bnc691fda62016-08-12 00:43:162929 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232930 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162931 MockWrite("GET / HTTP/1.1\r\n"
2932 "Host: www.example.org\r\n"
2933 "Connection: keep-alive\r\n"
2934 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322935 };
2936
2937 // Respond with 5 kb of response body.
2938 std::string large_body_string("Unauthorized");
2939 large_body_string.append(5 * 1024, ' ');
2940 large_body_string.append("\r\n");
2941
2942 MockRead data_reads1[] = {
2943 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2944 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2945 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2946 // 5134 = 12 + 5 * 1024 + 2
2947 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062948 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322949
2950 // Lastly, the server responds with the actual content.
2951 MockRead("HTTP/1.1 200 OK\r\n"),
2952 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502953 MockRead("Content-Length: 5\r\n\r\n"),
2954 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322955 };
2956
[email protected]2d0a4f92011-05-05 16:38:462957 // An incorrect reconnect would cause this to be read.
2958 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062959 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462960 };
2961
[email protected]31a2bfe2010-02-09 08:03:392962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2963 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462964 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2965 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2967 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322968
[email protected]49639fa2011-12-20 23:22:412969 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322970
bnc691fda62016-08-12 00:43:162971 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202972 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322974
2975 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012976 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322977
bnc691fda62016-08-12 00:43:162978 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522979 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042980 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322981
[email protected]49639fa2011-12-20 23:22:412982 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322983
bnc691fda62016-08-12 00:43:162984 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322986
2987 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012988 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322989
bnc691fda62016-08-12 00:43:162990 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522991 ASSERT_TRUE(response);
2992 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502993 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322994}
2995
2996// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312997// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012998TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312999 HttpRequestInfo request;
3000 request.method = "GET";
bncce36dca22015-04-21 22:11:233001 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103002 request.traffic_annotation =
3003 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313004
danakj1fd259a02016-04-16 03:17:093005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273006
[email protected]11203f012009-11-12 23:02:313007 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233008 MockWrite(
3009 "GET / HTTP/1.1\r\n"
3010 "Host: www.example.org\r\n"
3011 "Connection: keep-alive\r\n\r\n"),
3012 // This simulates the seemingly successful write to a closed connection
3013 // if the bug is not fixed.
3014 MockWrite(
3015 "GET / HTTP/1.1\r\n"
3016 "Host: www.example.org\r\n"
3017 "Connection: keep-alive\r\n"
3018 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313019 };
3020
3021 MockRead data_reads1[] = {
3022 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3023 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3024 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3025 MockRead("Content-Length: 14\r\n\r\n"),
3026 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063027 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313028 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063029 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313030 };
3031
bnc691fda62016-08-12 00:43:163032 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313033 // be issuing -- the final header line contains the credentials.
3034 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233035 MockWrite(
3036 "GET / HTTP/1.1\r\n"
3037 "Host: www.example.org\r\n"
3038 "Connection: keep-alive\r\n"
3039 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313040 };
3041
3042 // Lastly, the server responds with the actual content.
3043 MockRead data_reads2[] = {
3044 MockRead("HTTP/1.1 200 OK\r\n"),
3045 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503046 MockRead("Content-Length: 5\r\n\r\n"),
3047 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313048 };
3049
[email protected]31a2bfe2010-02-09 08:03:393050 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3051 data_writes1, arraysize(data_writes1));
3052 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3053 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073054 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3055 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313056
[email protected]49639fa2011-12-20 23:22:413057 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313058
bnc691fda62016-08-12 00:43:163059 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203060 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313062
3063 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013064 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313065
bnc691fda62016-08-12 00:43:163066 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523067 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043068 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313069
[email protected]49639fa2011-12-20 23:22:413070 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313071
bnc691fda62016-08-12 00:43:163072 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313074
3075 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013076 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313077
bnc691fda62016-08-12 00:43:163078 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523079 ASSERT_TRUE(response);
3080 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503081 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313082}
3083
[email protected]394816e92010-08-03 07:38:593084// Test the request-challenge-retry sequence for basic auth, over a connection
3085// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013086TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013087 HttpRequestInfo request;
3088 request.method = "GET";
bncce36dca22015-04-21 22:11:233089 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013090 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293091 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103092 request.traffic_annotation =
3093 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013094
3095 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593096 session_deps_.proxy_resolution_service =
3097 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513098 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013099 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013101
3102 // Since we have proxy, should try to establish tunnel.
3103 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543104 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173105 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543106 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013107 };
3108
mmenkee71e15332015-10-07 16:39:543109 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013110 // connection.
3111 MockRead data_reads1[] = {
3112 // No credentials.
3113 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3114 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543115 };
ttuttle34f63b52015-03-05 04:33:013116
mmenkee71e15332015-10-07 16:39:543117 // Since the first connection couldn't be reused, need to establish another
3118 // once given credentials.
3119 MockWrite data_writes2[] = {
3120 // After calling trans->RestartWithAuth(), this is the request we should
3121 // be issuing -- the final header line contains the credentials.
3122 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173123 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543124 "Proxy-Connection: keep-alive\r\n"
3125 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3126
3127 MockWrite("GET / HTTP/1.1\r\n"
3128 "Host: www.example.org\r\n"
3129 "Connection: keep-alive\r\n\r\n"),
3130 };
3131
3132 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013133 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3134
3135 MockRead("HTTP/1.1 200 OK\r\n"),
3136 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3137 MockRead("Content-Length: 5\r\n\r\n"),
3138 MockRead(SYNCHRONOUS, "hello"),
3139 };
3140
3141 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3142 data_writes1, arraysize(data_writes1));
3143 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543144 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3145 data_writes2, arraysize(data_writes2));
3146 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013147 SSLSocketDataProvider ssl(ASYNC, OK);
3148 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3149
3150 TestCompletionCallback callback1;
3151
bnc87dcefc2017-05-25 12:47:583152 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193153 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013154
3155 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013157
3158 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013159 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463160 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013161 log.GetEntries(&entries);
3162 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003163 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3164 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013165 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003166 entries, pos,
3167 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3168 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013169
3170 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523171 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013172 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523173 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013174 EXPECT_EQ(407, response->headers->response_code());
3175 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3176 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3177
3178 LoadTimingInfo load_timing_info;
3179 // CONNECT requests and responses are handled at the connect job level, so
3180 // the transaction does not yet have a connection.
3181 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3182
3183 TestCompletionCallback callback2;
3184
3185 rv =
3186 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013188
3189 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013190 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013191
3192 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523193 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013194
3195 EXPECT_TRUE(response->headers->IsKeepAlive());
3196 EXPECT_EQ(200, response->headers->response_code());
3197 EXPECT_EQ(5, response->headers->GetContentLength());
3198 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3199
3200 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523201 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013202
3203 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3204 TestLoadTimingNotReusedWithPac(load_timing_info,
3205 CONNECT_TIMING_HAS_SSL_TIMES);
3206
3207 trans.reset();
3208 session->CloseAllConnections();
3209}
3210
3211// Test the request-challenge-retry sequence for basic auth, over a connection
3212// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013213TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593214 HttpRequestInfo request;
3215 request.method = "GET";
bncce36dca22015-04-21 22:11:233216 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593217 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293218 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103219 request.traffic_annotation =
3220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593221
[email protected]cb9bf6ca2011-01-28 13:15:273222 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593223 session_deps_.proxy_resolution_service =
3224 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513225 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073226 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273228
[email protected]394816e92010-08-03 07:38:593229 // Since we have proxy, should try to establish tunnel.
3230 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543231 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173232 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543233 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113234 };
3235
mmenkee71e15332015-10-07 16:39:543236 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083237 // connection.
3238 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543239 // No credentials.
3240 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3241 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3242 MockRead("Proxy-Connection: close\r\n\r\n"),
3243 };
mmenkee0b5c882015-08-26 20:29:113244
mmenkee71e15332015-10-07 16:39:543245 MockWrite data_writes2[] = {
3246 // After calling trans->RestartWithAuth(), this is the request we should
3247 // be issuing -- the final header line contains the credentials.
3248 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173249 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543250 "Proxy-Connection: keep-alive\r\n"
3251 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083252
mmenkee71e15332015-10-07 16:39:543253 MockWrite("GET / HTTP/1.1\r\n"
3254 "Host: www.example.org\r\n"
3255 "Connection: keep-alive\r\n\r\n"),
3256 };
3257
3258 MockRead data_reads2[] = {
3259 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3260
3261 MockRead("HTTP/1.1 200 OK\r\n"),
3262 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3263 MockRead("Content-Length: 5\r\n\r\n"),
3264 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593265 };
3266
3267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3268 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543270 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3271 data_writes2, arraysize(data_writes2));
3272 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063273 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593275
[email protected]49639fa2011-12-20 23:22:413276 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593277
bnc87dcefc2017-05-25 12:47:583278 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193279 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503280
[email protected]49639fa2011-12-20 23:22:413281 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593283
3284 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013285 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463286 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403287 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593288 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003289 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3290 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593291 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403292 entries, pos,
mikecirone8b85c432016-09-08 19:11:003293 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3294 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593295
3296 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523297 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013298 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523299 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593300 EXPECT_EQ(407, response->headers->response_code());
3301 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043302 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593303
[email protected]029c83b62013-01-24 05:28:203304 LoadTimingInfo load_timing_info;
3305 // CONNECT requests and responses are handled at the connect job level, so
3306 // the transaction does not yet have a connection.
3307 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3308
[email protected]49639fa2011-12-20 23:22:413309 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593310
[email protected]49639fa2011-12-20 23:22:413311 rv = trans->RestartWithAuth(
3312 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013313 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593314
3315 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013316 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593317
3318 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523319 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593320
3321 EXPECT_TRUE(response->headers->IsKeepAlive());
3322 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503323 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593324 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3325
3326 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523327 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503328
[email protected]029c83b62013-01-24 05:28:203329 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3330 TestLoadTimingNotReusedWithPac(load_timing_info,
3331 CONNECT_TIMING_HAS_SSL_TIMES);
3332
[email protected]0b0bf032010-09-21 18:08:503333 trans.reset();
[email protected]102e27c2011-02-23 01:01:313334 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593335}
3336
[email protected]11203f012009-11-12 23:02:313337// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013338// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013339TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233340 // On the second pass, the body read of the auth challenge is synchronous, so
3341 // IsConnectedAndIdle returns false. The socket should still be drained and
3342 // reused. See http://crbug.com/544255.
3343 for (int i = 0; i < 2; ++i) {
3344 HttpRequestInfo request;
3345 request.method = "GET";
3346 request.url = GURL("https://www.example.org/");
3347 // Ensure that proxy authentication is attempted even
3348 // when the no authentication data flag is set.
3349 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103350 request.traffic_annotation =
3351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013352
mmenked39192ee2015-12-09 00:57:233353 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593354 session_deps_.proxy_resolution_service =
3355 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233356 BoundTestNetLog log;
3357 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093358 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013359
bnc691fda62016-08-12 00:43:163360 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013361
mmenked39192ee2015-12-09 00:57:233362 // Since we have proxy, should try to establish tunnel.
3363 MockWrite data_writes1[] = {
3364 MockWrite(ASYNC, 0,
3365 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3366 "Host: www.example.org:443\r\n"
3367 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013368
bnc691fda62016-08-12 00:43:163369 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233370 // be issuing -- the final header line contains the credentials.
3371 MockWrite(ASYNC, 3,
3372 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3373 "Host: www.example.org:443\r\n"
3374 "Proxy-Connection: keep-alive\r\n"
3375 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3376 };
ttuttle34f63b52015-03-05 04:33:013377
mmenked39192ee2015-12-09 00:57:233378 // The proxy responds to the connect with a 407, using a persistent
3379 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3380 MockRead data_reads1[] = {
3381 // No credentials.
3382 MockRead(ASYNC, 1,
3383 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3384 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3385 "Proxy-Connection: keep-alive\r\n"
3386 "Content-Length: 10\r\n\r\n"),
3387 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013388
mmenked39192ee2015-12-09 00:57:233389 // Wrong credentials (wrong password).
3390 MockRead(ASYNC, 4,
3391 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3392 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3393 "Proxy-Connection: keep-alive\r\n"
3394 "Content-Length: 10\r\n\r\n"),
3395 // No response body because the test stops reading here.
3396 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3397 };
ttuttle34f63b52015-03-05 04:33:013398
mmenked39192ee2015-12-09 00:57:233399 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3400 arraysize(data_writes1));
3401 data1.set_busy_before_sync_reads(true);
3402 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013403
mmenked39192ee2015-12-09 00:57:233404 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013405
bnc691fda62016-08-12 00:43:163406 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013407 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013408
mmenked39192ee2015-12-09 00:57:233409 TestNetLogEntry::List entries;
3410 log.GetEntries(&entries);
3411 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003412 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3413 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233414 ExpectLogContainsSomewhere(
3415 entries, pos,
mikecirone8b85c432016-09-08 19:11:003416 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3417 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013418
bnc691fda62016-08-12 00:43:163419 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233420 ASSERT_TRUE(response);
3421 ASSERT_TRUE(response->headers);
3422 EXPECT_TRUE(response->headers->IsKeepAlive());
3423 EXPECT_EQ(407, response->headers->response_code());
3424 EXPECT_EQ(10, response->headers->GetContentLength());
3425 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3426 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013427
mmenked39192ee2015-12-09 00:57:233428 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013429
mmenked39192ee2015-12-09 00:57:233430 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163431 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3432 callback2.callback());
robpercival214763f2016-07-01 23:27:013433 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013434
bnc691fda62016-08-12 00:43:163435 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233436 ASSERT_TRUE(response);
3437 ASSERT_TRUE(response->headers);
3438 EXPECT_TRUE(response->headers->IsKeepAlive());
3439 EXPECT_EQ(407, response->headers->response_code());
3440 EXPECT_EQ(10, response->headers->GetContentLength());
3441 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3442 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013443
mmenked39192ee2015-12-09 00:57:233444 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3445 // out of scope.
3446 session->CloseAllConnections();
3447 }
ttuttle34f63b52015-03-05 04:33:013448}
3449
3450// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3451// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013452TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233453 // On the second pass, the body read of the auth challenge is synchronous, so
3454 // IsConnectedAndIdle returns false. The socket should still be drained and
3455 // reused. See http://crbug.com/544255.
3456 for (int i = 0; i < 2; ++i) {
3457 HttpRequestInfo request;
3458 request.method = "GET";
3459 request.url = GURL("https://www.example.org/");
3460 // Ensure that proxy authentication is attempted even
3461 // when the no authentication data flag is set.
3462 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103463 request.traffic_annotation =
3464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233465
3466 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593467 session_deps_.proxy_resolution_service =
3468 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233469 BoundTestNetLog log;
3470 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233472
bnc691fda62016-08-12 00:43:163473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233474
3475 // Since we have proxy, should try to establish tunnel.
3476 MockWrite data_writes1[] = {
3477 MockWrite(ASYNC, 0,
3478 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3479 "Host: www.example.org:443\r\n"
3480 "Proxy-Connection: keep-alive\r\n\r\n"),
3481
bnc691fda62016-08-12 00:43:163482 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233483 // be issuing -- the final header line contains the credentials.
3484 MockWrite(ASYNC, 3,
3485 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3486 "Host: www.example.org:443\r\n"
3487 "Proxy-Connection: keep-alive\r\n"
3488 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3489 };
3490
3491 // The proxy responds to the connect with a 407, using a persistent
3492 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3493 MockRead data_reads1[] = {
3494 // No credentials.
3495 MockRead(ASYNC, 1,
3496 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3497 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3498 "Content-Length: 10\r\n\r\n"),
3499 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3500
3501 // Wrong credentials (wrong password).
3502 MockRead(ASYNC, 4,
3503 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3504 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3505 "Content-Length: 10\r\n\r\n"),
3506 // No response body because the test stops reading here.
3507 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3508 };
3509
3510 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3511 arraysize(data_writes1));
3512 data1.set_busy_before_sync_reads(true);
3513 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3514
3515 TestCompletionCallback callback1;
3516
bnc691fda62016-08-12 00:43:163517 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013518 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233519
3520 TestNetLogEntry::List entries;
3521 log.GetEntries(&entries);
3522 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003523 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3524 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233525 ExpectLogContainsSomewhere(
3526 entries, pos,
mikecirone8b85c432016-09-08 19:11:003527 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3528 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233529
bnc691fda62016-08-12 00:43:163530 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233531 ASSERT_TRUE(response);
3532 ASSERT_TRUE(response->headers);
3533 EXPECT_TRUE(response->headers->IsKeepAlive());
3534 EXPECT_EQ(407, response->headers->response_code());
3535 EXPECT_EQ(10, response->headers->GetContentLength());
3536 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3537 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3538
3539 TestCompletionCallback callback2;
3540
3541 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163542 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3543 callback2.callback());
robpercival214763f2016-07-01 23:27:013544 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233545
bnc691fda62016-08-12 00:43:163546 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233547 ASSERT_TRUE(response);
3548 ASSERT_TRUE(response->headers);
3549 EXPECT_TRUE(response->headers->IsKeepAlive());
3550 EXPECT_EQ(407, response->headers->response_code());
3551 EXPECT_EQ(10, response->headers->GetContentLength());
3552 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3553 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3554
3555 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3556 // out of scope.
3557 session->CloseAllConnections();
3558 }
3559}
3560
3561// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3562// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3563// the case the server sends extra data on the original socket, so it can't be
3564// reused.
bncd16676a2016-07-20 16:23:013565TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273566 HttpRequestInfo request;
3567 request.method = "GET";
bncce36dca22015-04-21 22:11:233568 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273569 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293570 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103571 request.traffic_annotation =
3572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273573
[email protected]2d2697f92009-02-18 21:00:323574 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593575 session_deps_.proxy_resolution_service =
3576 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513577 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073578 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323580
[email protected]2d2697f92009-02-18 21:00:323581 // Since we have proxy, should try to establish tunnel.
3582 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233583 MockWrite(ASYNC, 0,
3584 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173585 "Host: www.example.org:443\r\n"
3586 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233587 };
[email protected]2d2697f92009-02-18 21:00:323588
mmenked39192ee2015-12-09 00:57:233589 // The proxy responds to the connect with a 407, using a persistent, but sends
3590 // extra data, so the socket cannot be reused.
3591 MockRead data_reads1[] = {
3592 // No credentials.
3593 MockRead(ASYNC, 1,
3594 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3595 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3596 "Content-Length: 10\r\n\r\n"),
3597 MockRead(SYNCHRONOUS, 2, "0123456789"),
3598 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3599 };
3600
3601 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233602 // After calling trans->RestartWithAuth(), this is the request we should
3603 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233604 MockWrite(ASYNC, 0,
3605 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173606 "Host: www.example.org:443\r\n"
3607 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233608 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3609
3610 MockWrite(ASYNC, 2,
3611 "GET / HTTP/1.1\r\n"
3612 "Host: www.example.org\r\n"
3613 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323614 };
3615
mmenked39192ee2015-12-09 00:57:233616 MockRead data_reads2[] = {
3617 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323618
mmenked39192ee2015-12-09 00:57:233619 MockRead(ASYNC, 3,
3620 "HTTP/1.1 200 OK\r\n"
3621 "Content-Type: text/html; charset=iso-8859-1\r\n"
3622 "Content-Length: 5\r\n\r\n"),
3623 // No response body because the test stops reading here.
3624 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323625 };
3626
mmenked39192ee2015-12-09 00:57:233627 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3628 arraysize(data_writes1));
3629 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073630 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233631 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3632 arraysize(data_writes2));
3633 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3634 SSLSocketDataProvider ssl(ASYNC, OK);
3635 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323636
[email protected]49639fa2011-12-20 23:22:413637 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323638
bnc87dcefc2017-05-25 12:47:583639 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193640 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323641
mmenked39192ee2015-12-09 00:57:233642 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013643 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233644
mmenke43758e62015-05-04 21:09:463645 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403646 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393647 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003648 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3649 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393650 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403651 entries, pos,
mikecirone8b85c432016-09-08 19:11:003652 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3653 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323654
[email protected]1c773ea12009-04-28 19:58:423655 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243656 ASSERT_TRUE(response);
3657 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323658 EXPECT_TRUE(response->headers->IsKeepAlive());
3659 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423660 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043661 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323662
mmenked39192ee2015-12-09 00:57:233663 LoadTimingInfo load_timing_info;
3664 // CONNECT requests and responses are handled at the connect job level, so
3665 // the transaction does not yet have a connection.
3666 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3667
[email protected]49639fa2011-12-20 23:22:413668 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323669
mmenked39192ee2015-12-09 00:57:233670 rv =
3671 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013672 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323673
[email protected]2d2697f92009-02-18 21:00:323674 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233675 EXPECT_EQ(200, response->headers->response_code());
3676 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423677 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133678
mmenked39192ee2015-12-09 00:57:233679 // The password prompt info should not be set.
3680 EXPECT_FALSE(response->auth_challenge);
3681
3682 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3683 TestLoadTimingNotReusedWithPac(load_timing_info,
3684 CONNECT_TIMING_HAS_SSL_TIMES);
3685
3686 trans.reset();
[email protected]102e27c2011-02-23 01:01:313687 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323688}
3689
mmenkee71e15332015-10-07 16:39:543690// Test the case a proxy closes a socket while the challenge body is being
3691// drained.
bncd16676a2016-07-20 16:23:013692TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543693 HttpRequestInfo request;
3694 request.method = "GET";
3695 request.url = GURL("https://www.example.org/");
3696 // Ensure that proxy authentication is attempted even
3697 // when the no authentication data flag is set.
3698 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103699 request.traffic_annotation =
3700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543701
3702 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593703 session_deps_.proxy_resolution_service =
3704 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093705 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543706
bnc691fda62016-08-12 00:43:163707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543708
3709 // Since we have proxy, should try to establish tunnel.
3710 MockWrite data_writes1[] = {
3711 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173712 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543713 "Proxy-Connection: keep-alive\r\n\r\n"),
3714 };
3715
3716 // The proxy responds to the connect with a 407, using a persistent
3717 // connection.
3718 MockRead data_reads1[] = {
3719 // No credentials.
3720 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3721 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3722 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3723 // Server hands up in the middle of the body.
3724 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3725 };
3726
3727 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163728 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543729 // be issuing -- the final header line contains the credentials.
3730 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173731 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543732 "Proxy-Connection: keep-alive\r\n"
3733 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3734
3735 MockWrite("GET / HTTP/1.1\r\n"
3736 "Host: www.example.org\r\n"
3737 "Connection: keep-alive\r\n\r\n"),
3738 };
3739
3740 MockRead data_reads2[] = {
3741 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3742
3743 MockRead("HTTP/1.1 200 OK\r\n"),
3744 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3745 MockRead("Content-Length: 5\r\n\r\n"),
3746 MockRead(SYNCHRONOUS, "hello"),
3747 };
3748
3749 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3750 data_writes1, arraysize(data_writes1));
3751 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3752 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3753 data_writes2, arraysize(data_writes2));
3754 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3755 SSLSocketDataProvider ssl(ASYNC, OK);
3756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3757
3758 TestCompletionCallback callback;
3759
tfarina42834112016-09-22 13:38:203760 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013761 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543762
bnc691fda62016-08-12 00:43:163763 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543764 ASSERT_TRUE(response);
3765 ASSERT_TRUE(response->headers);
3766 EXPECT_TRUE(response->headers->IsKeepAlive());
3767 EXPECT_EQ(407, response->headers->response_code());
3768 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3769
bnc691fda62016-08-12 00:43:163770 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013771 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543772
bnc691fda62016-08-12 00:43:163773 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543774 ASSERT_TRUE(response);
3775 ASSERT_TRUE(response->headers);
3776 EXPECT_TRUE(response->headers->IsKeepAlive());
3777 EXPECT_EQ(200, response->headers->response_code());
3778 std::string body;
bnc691fda62016-08-12 00:43:163779 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543780 EXPECT_EQ("hello", body);
3781}
3782
[email protected]a8e9b162009-03-12 00:06:443783// Test that we don't read the response body when we fail to establish a tunnel,
3784// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013785TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273786 HttpRequestInfo request;
3787 request.method = "GET";
bncce36dca22015-04-21 22:11:233788 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103789 request.traffic_annotation =
3790 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273791
[email protected]a8e9b162009-03-12 00:06:443792 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593793 session_deps_.proxy_resolution_service =
3794 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443795
danakj1fd259a02016-04-16 03:17:093796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443797
bnc691fda62016-08-12 00:43:163798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443799
[email protected]a8e9b162009-03-12 00:06:443800 // Since we have proxy, should try to establish tunnel.
3801 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173802 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3803 "Host: www.example.org:443\r\n"
3804 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443805 };
3806
3807 // The proxy responds to the connect with a 407.
3808 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243809 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3810 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3811 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233812 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243813 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443814 };
3815
[email protected]31a2bfe2010-02-09 08:03:393816 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3817 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073818 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443819
[email protected]49639fa2011-12-20 23:22:413820 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443821
tfarina42834112016-09-22 13:38:203822 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443824
3825 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013826 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443827
bnc691fda62016-08-12 00:43:163828 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243829 ASSERT_TRUE(response);
3830 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443831 EXPECT_TRUE(response->headers->IsKeepAlive());
3832 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423833 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443834
3835 std::string response_data;
bnc691fda62016-08-12 00:43:163836 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013837 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183838
3839 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313840 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443841}
3842
ttuttle7933c112015-01-06 00:55:243843// Test that we don't pass extraneous headers from the proxy's response to the
3844// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013845TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243846 HttpRequestInfo request;
3847 request.method = "GET";
bncce36dca22015-04-21 22:11:233848 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103849 request.traffic_annotation =
3850 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243851
3852 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593853 session_deps_.proxy_resolution_service =
3854 ProxyResolutionService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243855
danakj1fd259a02016-04-16 03:17:093856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243857
bnc691fda62016-08-12 00:43:163858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243859
3860 // Since we have proxy, should try to establish tunnel.
3861 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173862 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3863 "Host: www.example.org:443\r\n"
3864 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243865 };
3866
3867 // The proxy responds to the connect with a 407.
3868 MockRead data_reads[] = {
3869 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3870 MockRead("X-Foo: bar\r\n"),
3871 MockRead("Set-Cookie: foo=bar\r\n"),
3872 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3873 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233874 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243875 };
3876
3877 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3878 arraysize(data_writes));
3879 session_deps_.socket_factory->AddSocketDataProvider(&data);
3880
3881 TestCompletionCallback callback;
3882
tfarina42834112016-09-22 13:38:203883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243885
3886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013887 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243888
bnc691fda62016-08-12 00:43:163889 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243890 ASSERT_TRUE(response);
3891 ASSERT_TRUE(response->headers);
3892 EXPECT_TRUE(response->headers->IsKeepAlive());
3893 EXPECT_EQ(407, response->headers->response_code());
3894 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3895 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3896 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3897
3898 std::string response_data;
bnc691fda62016-08-12 00:43:163899 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013900 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243901
3902 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3903 session->CloseAllConnections();
3904}
3905
[email protected]8fdbcd22010-05-05 02:54:523906// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3907// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013908TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523909 HttpRequestInfo request;
3910 request.method = "GET";
bncce36dca22015-04-21 22:11:233911 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103912 request.traffic_annotation =
3913 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523914
[email protected]cb9bf6ca2011-01-28 13:15:273915 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273918
[email protected]8fdbcd22010-05-05 02:54:523919 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233920 MockWrite(
3921 "GET / HTTP/1.1\r\n"
3922 "Host: www.example.org\r\n"
3923 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523924 };
3925
3926 MockRead data_reads1[] = {
3927 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3928 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3929 // Large content-length -- won't matter, as connection will be reset.
3930 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063931 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523932 };
3933
3934 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3935 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523937
[email protected]49639fa2011-12-20 23:22:413938 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523939
tfarina42834112016-09-22 13:38:203940 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523942
3943 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013944 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523945}
3946
[email protected]7a67a8152010-11-05 18:31:103947// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3948// through a non-authenticating proxy. The request should fail with
3949// ERR_UNEXPECTED_PROXY_AUTH.
3950// Note that it is impossible to detect if an HTTP server returns a 407 through
3951// a non-authenticating proxy - there is nothing to indicate whether the
3952// response came from the proxy or the server, so it is treated as if the proxy
3953// issued the challenge.
bncd16676a2016-07-20 16:23:013954TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273955 HttpRequestInfo request;
3956 request.method = "GET";
bncce36dca22015-04-21 22:11:233957 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103958 request.traffic_annotation =
3959 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273960
Lily Houghton8c2f97d2018-01-22 05:06:593961 session_deps_.proxy_resolution_service =
3962 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513963 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073964 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093965 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103966
[email protected]7a67a8152010-11-05 18:31:103967 // Since we have proxy, should try to establish tunnel.
3968 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173969 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3970 "Host: www.example.org:443\r\n"
3971 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103972
rsleevidb16bb02015-11-12 23:47:173973 MockWrite("GET / HTTP/1.1\r\n"
3974 "Host: www.example.org\r\n"
3975 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103976 };
3977
3978 MockRead data_reads1[] = {
3979 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3980
3981 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3982 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3983 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063984 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103985 };
3986
3987 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3988 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073989 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063990 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073991 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103992
[email protected]49639fa2011-12-20 23:22:413993 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103994
bnc691fda62016-08-12 00:43:163995 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103996
bnc691fda62016-08-12 00:43:163997 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103999
4000 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014001 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464002 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404003 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104004 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004005 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4006 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104007 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404008 entries, pos,
mikecirone8b85c432016-09-08 19:11:004009 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4010 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104011}
[email protected]2df19bb2010-08-25 20:13:464012
mmenke2a1781d2015-10-07 19:25:334013// Test a proxy auth scheme that allows default credentials and a proxy server
4014// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014015TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334016 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4017 HttpRequestInfo request;
4018 request.method = "GET";
4019 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104020 request.traffic_annotation =
4021 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334022
4023 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594024 session_deps_.proxy_resolution_service =
4025 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334026
Jeremy Roman0579ed62017-08-29 15:56:194027 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334028 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194029 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334030 mock_handler->set_allows_default_credentials(true);
4031 auth_handler_factory->AddMockHandler(mock_handler.release(),
4032 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484033 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334034
4035 // Add NetLog just so can verify load timing information gets a NetLog ID.
4036 NetLog net_log;
4037 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094038 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334039
4040 // Since we have proxy, should try to establish tunnel.
4041 MockWrite data_writes1[] = {
4042 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174043 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334044 "Proxy-Connection: keep-alive\r\n\r\n"),
4045 };
4046
4047 // The proxy responds to the connect with a 407, using a non-persistent
4048 // connection.
4049 MockRead data_reads1[] = {
4050 // No credentials.
4051 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4052 MockRead("Proxy-Authenticate: Mock\r\n"),
4053 MockRead("Proxy-Connection: close\r\n\r\n"),
4054 };
4055
4056 // Since the first connection couldn't be reused, need to establish another
4057 // once given credentials.
4058 MockWrite data_writes2[] = {
4059 // After calling trans->RestartWithAuth(), this is the request we should
4060 // be issuing -- the final header line contains the credentials.
4061 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174062 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334063 "Proxy-Connection: keep-alive\r\n"
4064 "Proxy-Authorization: auth_token\r\n\r\n"),
4065
4066 MockWrite("GET / HTTP/1.1\r\n"
4067 "Host: www.example.org\r\n"
4068 "Connection: keep-alive\r\n\r\n"),
4069 };
4070
4071 MockRead data_reads2[] = {
4072 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4073
4074 MockRead("HTTP/1.1 200 OK\r\n"),
4075 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4076 MockRead("Content-Length: 5\r\n\r\n"),
4077 MockRead(SYNCHRONOUS, "hello"),
4078 };
4079
4080 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4081 data_writes1, arraysize(data_writes1));
4082 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4083 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4084 data_writes2, arraysize(data_writes2));
4085 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4086 SSLSocketDataProvider ssl(ASYNC, OK);
4087 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4088
bnc87dcefc2017-05-25 12:47:584089 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194090 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334091
4092 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204093 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014094 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334095
4096 const HttpResponseInfo* response = trans->GetResponseInfo();
4097 ASSERT_TRUE(response);
4098 ASSERT_TRUE(response->headers);
4099 EXPECT_FALSE(response->headers->IsKeepAlive());
4100 EXPECT_EQ(407, response->headers->response_code());
4101 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4102 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524103 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334104
4105 LoadTimingInfo load_timing_info;
4106 // CONNECT requests and responses are handled at the connect job level, so
4107 // the transaction does not yet have a connection.
4108 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4109
4110 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014111 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334112 response = trans->GetResponseInfo();
4113 ASSERT_TRUE(response);
4114 ASSERT_TRUE(response->headers);
4115 EXPECT_TRUE(response->headers->IsKeepAlive());
4116 EXPECT_EQ(200, response->headers->response_code());
4117 EXPECT_EQ(5, response->headers->GetContentLength());
4118 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4119
4120 // The password prompt info should not be set.
4121 EXPECT_FALSE(response->auth_challenge);
4122
4123 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4124 TestLoadTimingNotReusedWithPac(load_timing_info,
4125 CONNECT_TIMING_HAS_SSL_TIMES);
4126
4127 trans.reset();
4128 session->CloseAllConnections();
4129}
4130
4131// Test a proxy auth scheme that allows default credentials and a proxy server
4132// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014133TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334134 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4135 HttpRequestInfo request;
4136 request.method = "GET";
4137 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104138 request.traffic_annotation =
4139 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334140
4141 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594142 session_deps_.proxy_resolution_service =
4143 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334144
Jeremy Roman0579ed62017-08-29 15:56:194145 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334146 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194147 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334148 mock_handler->set_allows_default_credentials(true);
4149 auth_handler_factory->AddMockHandler(mock_handler.release(),
4150 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484151 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334152
4153 // Add NetLog just so can verify load timing information gets a NetLog ID.
4154 NetLog net_log;
4155 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094156 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334157
4158 // Should try to establish tunnel.
4159 MockWrite data_writes1[] = {
4160 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174161 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334162 "Proxy-Connection: keep-alive\r\n\r\n"),
4163
4164 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174165 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334166 "Proxy-Connection: keep-alive\r\n"
4167 "Proxy-Authorization: auth_token\r\n\r\n"),
4168 };
4169
4170 // The proxy responds to the connect with a 407, using a non-persistent
4171 // connection.
4172 MockRead data_reads1[] = {
4173 // No credentials.
4174 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4175 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4176 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4177 };
4178
4179 // Since the first connection was closed, need to establish another once given
4180 // credentials.
4181 MockWrite data_writes2[] = {
4182 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174183 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334184 "Proxy-Connection: keep-alive\r\n"
4185 "Proxy-Authorization: auth_token\r\n\r\n"),
4186
4187 MockWrite("GET / HTTP/1.1\r\n"
4188 "Host: www.example.org\r\n"
4189 "Connection: keep-alive\r\n\r\n"),
4190 };
4191
4192 MockRead data_reads2[] = {
4193 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4194
4195 MockRead("HTTP/1.1 200 OK\r\n"),
4196 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4197 MockRead("Content-Length: 5\r\n\r\n"),
4198 MockRead(SYNCHRONOUS, "hello"),
4199 };
4200
4201 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4202 data_writes1, arraysize(data_writes1));
4203 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4204 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4205 data_writes2, arraysize(data_writes2));
4206 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4207 SSLSocketDataProvider ssl(ASYNC, OK);
4208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4209
bnc87dcefc2017-05-25 12:47:584210 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194211 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334212
4213 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204214 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014215 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334216
4217 const HttpResponseInfo* response = trans->GetResponseInfo();
4218 ASSERT_TRUE(response);
4219 ASSERT_TRUE(response->headers);
4220 EXPECT_TRUE(response->headers->IsKeepAlive());
4221 EXPECT_EQ(407, response->headers->response_code());
4222 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4223 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4224 EXPECT_FALSE(response->auth_challenge);
4225
4226 LoadTimingInfo load_timing_info;
4227 // CONNECT requests and responses are handled at the connect job level, so
4228 // the transaction does not yet have a connection.
4229 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4230
4231 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014232 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334233
4234 response = trans->GetResponseInfo();
4235 ASSERT_TRUE(response);
4236 ASSERT_TRUE(response->headers);
4237 EXPECT_TRUE(response->headers->IsKeepAlive());
4238 EXPECT_EQ(200, response->headers->response_code());
4239 EXPECT_EQ(5, response->headers->GetContentLength());
4240 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4241
4242 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524243 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334244
4245 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4246 TestLoadTimingNotReusedWithPac(load_timing_info,
4247 CONNECT_TIMING_HAS_SSL_TIMES);
4248
4249 trans.reset();
4250 session->CloseAllConnections();
4251}
4252
4253// Test a proxy auth scheme that allows default credentials and a proxy server
4254// that hangs up when credentials are initially sent, and hangs up again when
4255// they are retried.
bncd16676a2016-07-20 16:23:014256TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334257 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4258 HttpRequestInfo request;
4259 request.method = "GET";
4260 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104261 request.traffic_annotation =
4262 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334263
4264 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594265 session_deps_.proxy_resolution_service =
4266 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334267
Jeremy Roman0579ed62017-08-29 15:56:194268 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334269 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194270 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334271 mock_handler->set_allows_default_credentials(true);
4272 auth_handler_factory->AddMockHandler(mock_handler.release(),
4273 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484274 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334275
4276 // Add NetLog just so can verify load timing information gets a NetLog ID.
4277 NetLog net_log;
4278 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094279 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334280
4281 // Should try to establish tunnel.
4282 MockWrite data_writes1[] = {
4283 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174284 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334285 "Proxy-Connection: keep-alive\r\n\r\n"),
4286
4287 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174288 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334289 "Proxy-Connection: keep-alive\r\n"
4290 "Proxy-Authorization: auth_token\r\n\r\n"),
4291 };
4292
4293 // The proxy responds to the connect with a 407, and then hangs up after the
4294 // second request is sent.
4295 MockRead data_reads1[] = {
4296 // No credentials.
4297 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4298 MockRead("Content-Length: 0\r\n"),
4299 MockRead("Proxy-Connection: keep-alive\r\n"),
4300 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4301 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4302 };
4303
4304 // HttpNetworkTransaction sees a reused connection that was closed with
4305 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4306 // request.
4307 MockWrite data_writes2[] = {
4308 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174309 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334310 "Proxy-Connection: keep-alive\r\n\r\n"),
4311 };
4312
4313 // The proxy, having had more than enough of us, just hangs up.
4314 MockRead data_reads2[] = {
4315 // No credentials.
4316 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4317 };
4318
4319 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4320 data_writes1, arraysize(data_writes1));
4321 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4322 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4323 data_writes2, arraysize(data_writes2));
4324 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4325
bnc87dcefc2017-05-25 12:47:584326 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194327 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334328
4329 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204330 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014331 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334332
4333 const HttpResponseInfo* response = trans->GetResponseInfo();
4334 ASSERT_TRUE(response);
4335 ASSERT_TRUE(response->headers);
4336 EXPECT_TRUE(response->headers->IsKeepAlive());
4337 EXPECT_EQ(407, response->headers->response_code());
4338 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4339 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4340 EXPECT_FALSE(response->auth_challenge);
4341
4342 LoadTimingInfo load_timing_info;
4343 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4344
4345 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014346 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334347
4348 trans.reset();
4349 session->CloseAllConnections();
4350}
4351
4352// Test a proxy auth scheme that allows default credentials and a proxy server
4353// that hangs up when credentials are initially sent, and sends a challenge
4354// again they are retried.
bncd16676a2016-07-20 16:23:014355TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334356 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4357 HttpRequestInfo request;
4358 request.method = "GET";
4359 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104360 request.traffic_annotation =
4361 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334362
4363 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594364 session_deps_.proxy_resolution_service =
4365 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334366
Jeremy Roman0579ed62017-08-29 15:56:194367 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334368 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194369 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334370 mock_handler->set_allows_default_credentials(true);
4371 auth_handler_factory->AddMockHandler(mock_handler.release(),
4372 HttpAuth::AUTH_PROXY);
4373 // Add another handler for the second challenge. It supports default
4374 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194375 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334376 mock_handler->set_allows_default_credentials(true);
4377 auth_handler_factory->AddMockHandler(mock_handler.release(),
4378 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484379 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334380
4381 // Add NetLog just so can verify load timing information gets a NetLog ID.
4382 NetLog net_log;
4383 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094384 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334385
4386 // Should try to establish tunnel.
4387 MockWrite data_writes1[] = {
4388 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174389 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334390 "Proxy-Connection: keep-alive\r\n\r\n"),
4391 };
4392
4393 // The proxy responds to the connect with a 407, using a non-persistent
4394 // connection.
4395 MockRead data_reads1[] = {
4396 // No credentials.
4397 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4398 MockRead("Proxy-Authenticate: Mock\r\n"),
4399 MockRead("Proxy-Connection: close\r\n\r\n"),
4400 };
4401
4402 // Since the first connection was closed, need to establish another once given
4403 // credentials.
4404 MockWrite data_writes2[] = {
4405 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174406 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334407 "Proxy-Connection: keep-alive\r\n"
4408 "Proxy-Authorization: auth_token\r\n\r\n"),
4409 };
4410
4411 MockRead data_reads2[] = {
4412 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4413 MockRead("Proxy-Authenticate: Mock\r\n"),
4414 MockRead("Proxy-Connection: close\r\n\r\n"),
4415 };
4416
4417 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4418 data_writes1, arraysize(data_writes1));
4419 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4420 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4421 data_writes2, arraysize(data_writes2));
4422 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4423 SSLSocketDataProvider ssl(ASYNC, OK);
4424 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4425
bnc87dcefc2017-05-25 12:47:584426 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194427 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334428
4429 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204430 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014431 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334432
4433 const HttpResponseInfo* response = trans->GetResponseInfo();
4434 ASSERT_TRUE(response);
4435 ASSERT_TRUE(response->headers);
4436 EXPECT_EQ(407, response->headers->response_code());
4437 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4438 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4439 EXPECT_FALSE(response->auth_challenge);
4440
4441 LoadTimingInfo load_timing_info;
4442 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4443
4444 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014445 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334446 response = trans->GetResponseInfo();
4447 ASSERT_TRUE(response);
4448 ASSERT_TRUE(response->headers);
4449 EXPECT_EQ(407, response->headers->response_code());
4450 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4451 EXPECT_TRUE(response->auth_challenge);
4452
4453 trans.reset();
4454 session->CloseAllConnections();
4455}
4456
asankae2257db2016-10-11 22:03:164457// A more nuanced test than GenerateAuthToken test which asserts that
4458// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4459// unnecessarily invalidated, and that if the server co-operates, the
4460// authentication handshake can continue with the same scheme but with a
4461// different identity.
4462TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4463 HttpRequestInfo request;
4464 request.method = "GET";
4465 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104466 request.traffic_annotation =
4467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164468
Jeremy Roman0579ed62017-08-29 15:56:194469 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164470 auth_handler_factory->set_do_init_from_challenge(true);
4471
4472 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194473 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164474 mock_handler->set_allows_default_credentials(true);
4475 mock_handler->set_allows_explicit_credentials(true);
4476 mock_handler->set_connection_based(true);
4477 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4478 auth_handler_factory->AddMockHandler(mock_handler.release(),
4479 HttpAuth::AUTH_SERVER);
4480
4481 // Add another handler for the second challenge. It supports default
4482 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194483 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164484 mock_handler->set_allows_default_credentials(true);
4485 mock_handler->set_allows_explicit_credentials(true);
4486 mock_handler->set_connection_based(true);
4487 auth_handler_factory->AddMockHandler(mock_handler.release(),
4488 HttpAuth::AUTH_SERVER);
4489 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4490
4491 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4492
4493 MockWrite data_writes1[] = {
4494 MockWrite("GET / HTTP/1.1\r\n"
4495 "Host: www.example.org\r\n"
4496 "Connection: keep-alive\r\n\r\n"),
4497 };
4498
4499 MockRead data_reads1[] = {
4500 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4501 "WWW-Authenticate: Mock\r\n"
4502 "Connection: keep-alive\r\n\r\n"),
4503 };
4504
4505 // Identical to data_writes1[]. The AuthHandler encounters a
4506 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4507 // transaction procceds without an authorization header.
4508 MockWrite data_writes2[] = {
4509 MockWrite("GET / HTTP/1.1\r\n"
4510 "Host: www.example.org\r\n"
4511 "Connection: keep-alive\r\n\r\n"),
4512 };
4513
4514 MockRead data_reads2[] = {
4515 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4516 "WWW-Authenticate: Mock\r\n"
4517 "Connection: keep-alive\r\n\r\n"),
4518 };
4519
4520 MockWrite data_writes3[] = {
4521 MockWrite("GET / HTTP/1.1\r\n"
4522 "Host: www.example.org\r\n"
4523 "Connection: keep-alive\r\n"
4524 "Authorization: auth_token\r\n\r\n"),
4525 };
4526
4527 MockRead data_reads3[] = {
4528 MockRead("HTTP/1.1 200 OK\r\n"
4529 "Content-Length: 5\r\n"
4530 "Content-Type: text/plain\r\n"
4531 "Connection: keep-alive\r\n\r\n"
4532 "Hello"),
4533 };
4534
4535 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4536 data_writes1, arraysize(data_writes1));
4537 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4538
4539 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4540 data_writes2, arraysize(data_writes2));
4541 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4542
4543 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4544 data_writes3, arraysize(data_writes3));
4545 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4546
bnc87dcefc2017-05-25 12:47:584547 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194548 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164549
4550 TestCompletionCallback callback;
4551 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4552 EXPECT_THAT(callback.GetResult(rv), IsOk());
4553
4554 const HttpResponseInfo* response = trans->GetResponseInfo();
4555 ASSERT_TRUE(response);
4556 ASSERT_TRUE(response->headers);
4557 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4558
4559 // The following three tests assert that an authentication challenge was
4560 // received and that the stack is ready to respond to the challenge using
4561 // ambient credentials.
4562 EXPECT_EQ(401, response->headers->response_code());
4563 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4564 EXPECT_FALSE(response->auth_challenge);
4565
4566 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4567 EXPECT_THAT(callback.GetResult(rv), IsOk());
4568 response = trans->GetResponseInfo();
4569 ASSERT_TRUE(response);
4570 ASSERT_TRUE(response->headers);
4571
4572 // The following three tests assert that an authentication challenge was
4573 // received and that the stack needs explicit credentials before it is ready
4574 // to respond to the challenge.
4575 EXPECT_EQ(401, response->headers->response_code());
4576 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4577 EXPECT_TRUE(response->auth_challenge);
4578
4579 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4580 EXPECT_THAT(callback.GetResult(rv), IsOk());
4581 response = trans->GetResponseInfo();
4582 ASSERT_TRUE(response);
4583 ASSERT_TRUE(response->headers);
4584 EXPECT_EQ(200, response->headers->response_code());
4585
4586 trans.reset();
4587 session->CloseAllConnections();
4588}
4589
Matt Menked1eb6d42018-01-17 04:54:064590// Proxy resolver that returns a proxy with the same host and port for different
4591// schemes, based on the path of the URL being requests.
4592class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4593 public:
4594 SameProxyWithDifferentSchemesProxyResolver() {}
4595 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4596
4597 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4598
4599 static HostPortPair ProxyHostPortPair() {
4600 return HostPortPair::FromString(ProxyHostPortPairAsString());
4601 }
4602
4603 // ProxyResolver implementation.
4604 int GetProxyForURL(const GURL& url,
4605 ProxyInfo* results,
4606 const CompletionCallback& callback,
4607 std::unique_ptr<Request>* request,
4608 const NetLogWithSource& /*net_log*/) override {
4609 *results = ProxyInfo();
4610 if (url.path() == "/socks4") {
4611 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4612 return OK;
4613 }
4614 if (url.path() == "/socks5") {
4615 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4616 return OK;
4617 }
4618 if (url.path() == "/http") {
4619 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4620 return OK;
4621 }
4622 if (url.path() == "/https") {
4623 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4624 return OK;
4625 }
4626 NOTREACHED();
4627 return ERR_NOT_IMPLEMENTED;
4628 }
4629
4630 private:
4631 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4632};
4633
4634class SameProxyWithDifferentSchemesProxyResolverFactory
4635 : public ProxyResolverFactory {
4636 public:
4637 SameProxyWithDifferentSchemesProxyResolverFactory()
4638 : ProxyResolverFactory(false) {}
4639
Lily Houghton99597862018-03-07 16:40:424640 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4641 std::unique_ptr<ProxyResolver>* resolver,
4642 const CompletionCallback& callback,
4643 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064644 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4645 return OK;
4646 }
4647
4648 private:
4649 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4650};
4651
4652// Check that when different proxy schemes are all applied to a proxy at the
4653// same address, the sonnections are not grouped together. i.e., a request to
4654// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4655// request to foo.com using proxy.com as an HTTP proxy.
4656TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Lily Houghton8c2f97d2018-01-22 05:06:594657 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Matt Menked1eb6d42018-01-17 04:54:064658 std::make_unique<ProxyConfigServiceFixed>(
4659 ProxyConfig::CreateAutoDetect()),
4660 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4661 nullptr);
4662
4663 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4664
4665 MockWrite socks_writes[] = {
4666 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4667 kSOCKS4OkRequestLocalHostPort80Length),
4668 MockWrite(SYNCHRONOUS,
4669 "GET /socks4 HTTP/1.1\r\n"
4670 "Host: test\r\n"
4671 "Connection: keep-alive\r\n\r\n"),
4672 };
4673 MockRead socks_reads[] = {
4674 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4675 MockRead("HTTP/1.0 200 OK\r\n"
4676 "Connection: keep-alive\r\n"
4677 "Content-Length: 15\r\n\r\n"
4678 "SOCKS4 Response"),
4679 };
4680 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4681 socks_writes, arraysize(socks_writes));
4682 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4683
4684 const char kSOCKS5Request[] = {
4685 0x05, // Version
4686 0x01, // Command (CONNECT)
4687 0x00, // Reserved
4688 0x03, // Address type (DOMAINNAME)
4689 0x04, // Length of domain (4)
4690 't', 'e', 's', 't', // Domain string
4691 0x00, 0x50, // 16-bit port (80)
4692 };
4693 MockWrite socks5_writes[] = {
4694 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4695 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4696 MockWrite(SYNCHRONOUS,
4697 "GET /socks5 HTTP/1.1\r\n"
4698 "Host: test\r\n"
4699 "Connection: keep-alive\r\n\r\n"),
4700 };
4701 MockRead socks5_reads[] = {
4702 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4703 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4704 MockRead("HTTP/1.0 200 OK\r\n"
4705 "Connection: keep-alive\r\n"
4706 "Content-Length: 15\r\n\r\n"
4707 "SOCKS5 Response"),
4708 };
4709 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4710 socks5_writes, arraysize(socks5_writes));
4711 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4712
4713 MockWrite http_writes[] = {
4714 MockWrite(SYNCHRONOUS,
4715 "GET http://test/http HTTP/1.1\r\n"
4716 "Host: test\r\n"
4717 "Proxy-Connection: keep-alive\r\n\r\n"),
4718 };
4719 MockRead http_reads[] = {
4720 MockRead("HTTP/1.1 200 OK\r\n"
4721 "Proxy-Connection: keep-alive\r\n"
4722 "Content-Length: 13\r\n\r\n"
4723 "HTTP Response"),
4724 };
4725 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4726 http_writes, arraysize(http_writes));
4727 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4728
4729 MockWrite https_writes[] = {
4730 MockWrite(SYNCHRONOUS,
4731 "GET http://test/https HTTP/1.1\r\n"
4732 "Host: test\r\n"
4733 "Proxy-Connection: keep-alive\r\n\r\n"),
4734 };
4735 MockRead https_reads[] = {
4736 MockRead("HTTP/1.1 200 OK\r\n"
4737 "Proxy-Connection: keep-alive\r\n"
4738 "Content-Length: 14\r\n\r\n"
4739 "HTTPS Response"),
4740 };
4741 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4742 https_writes, arraysize(https_writes));
4743 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4744 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4745 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4746
4747 struct TestCase {
4748 GURL url;
4749 std::string expected_response;
4750 // How many idle sockets there should be in the SOCKS proxy socket pool
4751 // after the test.
4752 int expected_idle_socks_sockets;
4753 // How many idle sockets there should be in the HTTP proxy socket pool after
4754 // the test.
4755 int expected_idle_http_sockets;
4756 } const kTestCases[] = {
4757 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4758 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4759 {GURL("http://test/http"), "HTTP Response", 2, 1},
4760 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4761 };
4762
4763 for (const auto& test_case : kTestCases) {
4764 HttpRequestInfo request;
4765 request.method = "GET";
4766 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:104767 request.traffic_annotation =
4768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064769 std::unique_ptr<HttpNetworkTransaction> trans =
4770 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4771 session.get());
4772 TestCompletionCallback callback;
4773 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4774 EXPECT_THAT(callback.GetResult(rv), IsOk());
4775
4776 const HttpResponseInfo* response = trans->GetResponseInfo();
4777 ASSERT_TRUE(response);
4778 ASSERT_TRUE(response->headers);
4779 EXPECT_EQ(200, response->headers->response_code());
4780 std::string response_data;
4781 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4782 EXPECT_EQ(test_case.expected_response, response_data);
4783
4784 // Return the socket to the socket pool, so can make sure it's not used for
4785 // the next requests.
4786 trans.reset();
4787 base::RunLoop().RunUntilIdle();
4788
4789 // Check the number of idle sockets in the pool, to make sure that used
4790 // sockets are indeed being returned to the socket pool. If each request
4791 // doesn't return an idle socket to the pool, the test would incorrectly
4792 // pass.
4793 EXPECT_EQ(
4794 test_case.expected_idle_socks_sockets,
4795 session
4796 ->GetSocketPoolForSOCKSProxy(
4797 HttpNetworkSession::NORMAL_SOCKET_POOL,
4798 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4799 ->IdleSocketCount());
4800 EXPECT_EQ(
4801 test_case.expected_idle_http_sockets,
4802 session
4803 ->GetSocketPoolForHTTPProxy(
4804 HttpNetworkSession::NORMAL_SOCKET_POOL,
4805 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4806 ->IdleSocketCount());
4807 }
4808}
4809
[email protected]029c83b62013-01-24 05:28:204810// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014811TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204812 HttpRequestInfo request1;
4813 request1.method = "GET";
bncce36dca22015-04-21 22:11:234814 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104815 request1.traffic_annotation =
4816 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204817
4818 HttpRequestInfo request2;
4819 request2.method = "GET";
bncce36dca22015-04-21 22:11:234820 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104821 request2.traffic_annotation =
4822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204823
4824 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594825 session_deps_.proxy_resolution_service =
4826 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514827 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074828 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204830
4831 // Since we have proxy, should try to establish tunnel.
4832 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174833 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4834 "Host: www.example.org:443\r\n"
4835 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204836
rsleevidb16bb02015-11-12 23:47:174837 MockWrite("GET /1 HTTP/1.1\r\n"
4838 "Host: www.example.org\r\n"
4839 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204840
rsleevidb16bb02015-11-12 23:47:174841 MockWrite("GET /2 HTTP/1.1\r\n"
4842 "Host: www.example.org\r\n"
4843 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204844 };
4845
4846 // The proxy responds to the connect with a 407, using a persistent
4847 // connection.
4848 MockRead data_reads1[] = {
4849 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4850
4851 MockRead("HTTP/1.1 200 OK\r\n"),
4852 MockRead("Content-Length: 1\r\n\r\n"),
4853 MockRead(SYNCHRONOUS, "1"),
4854
4855 MockRead("HTTP/1.1 200 OK\r\n"),
4856 MockRead("Content-Length: 2\r\n\r\n"),
4857 MockRead(SYNCHRONOUS, "22"),
4858 };
4859
4860 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4861 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074862 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204863 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204865
4866 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584867 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194868 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204869
4870 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204872
4873 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014874 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204875
4876 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524877 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474878 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524879 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204880 EXPECT_EQ(1, response1->headers->GetContentLength());
4881
4882 LoadTimingInfo load_timing_info1;
4883 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4884 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4885
4886 trans1.reset();
4887
4888 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584889 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194890 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204891
4892 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204894
4895 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014896 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204897
4898 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524899 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474900 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524901 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204902 EXPECT_EQ(2, response2->headers->GetContentLength());
4903
4904 LoadTimingInfo load_timing_info2;
4905 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4906 TestLoadTimingReused(load_timing_info2);
4907
4908 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4909
4910 trans2.reset();
4911 session->CloseAllConnections();
4912}
4913
4914// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014915TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204916 HttpRequestInfo request1;
4917 request1.method = "GET";
bncce36dca22015-04-21 22:11:234918 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104919 request1.traffic_annotation =
4920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204921
4922 HttpRequestInfo request2;
4923 request2.method = "GET";
bncce36dca22015-04-21 22:11:234924 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104925 request2.traffic_annotation =
4926 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204927
4928 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594929 session_deps_.proxy_resolution_service =
4930 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514931 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074932 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094933 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204934
4935 // Since we have proxy, should try to establish tunnel.
4936 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174937 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4938 "Host: www.example.org:443\r\n"
4939 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204940
rsleevidb16bb02015-11-12 23:47:174941 MockWrite("GET /1 HTTP/1.1\r\n"
4942 "Host: www.example.org\r\n"
4943 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204944
rsleevidb16bb02015-11-12 23:47:174945 MockWrite("GET /2 HTTP/1.1\r\n"
4946 "Host: www.example.org\r\n"
4947 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204948 };
4949
4950 // The proxy responds to the connect with a 407, using a persistent
4951 // connection.
4952 MockRead data_reads1[] = {
4953 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4954
4955 MockRead("HTTP/1.1 200 OK\r\n"),
4956 MockRead("Content-Length: 1\r\n\r\n"),
4957 MockRead(SYNCHRONOUS, "1"),
4958
4959 MockRead("HTTP/1.1 200 OK\r\n"),
4960 MockRead("Content-Length: 2\r\n\r\n"),
4961 MockRead(SYNCHRONOUS, "22"),
4962 };
4963
4964 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4965 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204967 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204969
4970 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584971 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194972 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204973
4974 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204976
4977 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014978 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204979
4980 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524981 ASSERT_TRUE(response1);
4982 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204983 EXPECT_EQ(1, response1->headers->GetContentLength());
4984
4985 LoadTimingInfo load_timing_info1;
4986 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4987 TestLoadTimingNotReusedWithPac(load_timing_info1,
4988 CONNECT_TIMING_HAS_SSL_TIMES);
4989
4990 trans1.reset();
4991
4992 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584993 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194994 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204995
4996 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204998
4999 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015000 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205001
5002 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525003 ASSERT_TRUE(response2);
5004 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205005 EXPECT_EQ(2, response2->headers->GetContentLength());
5006
5007 LoadTimingInfo load_timing_info2;
5008 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5009 TestLoadTimingReusedWithPac(load_timing_info2);
5010
5011 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5012
5013 trans2.reset();
5014 session->CloseAllConnections();
5015}
5016
[email protected]2df19bb2010-08-25 20:13:465017// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015018TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275019 HttpRequestInfo request;
5020 request.method = "GET";
bncce36dca22015-04-21 22:11:235021 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105022 request.traffic_annotation =
5023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275024
[email protected]2df19bb2010-08-25 20:13:465025 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595026 session_deps_.proxy_resolution_service =
5027 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515028 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075029 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465031
[email protected]2df19bb2010-08-25 20:13:465032 // Since we have proxy, should use full url
5033 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235034 MockWrite(
5035 "GET http://www.example.org/ HTTP/1.1\r\n"
5036 "Host: www.example.org\r\n"
5037 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465038 };
5039
5040 MockRead data_reads1[] = {
5041 MockRead("HTTP/1.1 200 OK\r\n"),
5042 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5043 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065044 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465045 };
5046
5047 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5048 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075049 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065050 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465052
[email protected]49639fa2011-12-20 23:22:415053 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465054
bnc691fda62016-08-12 00:43:165055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505056
bnc691fda62016-08-12 00:43:165057 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465059
5060 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015061 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465062
[email protected]58e32bb2013-01-21 18:23:255063 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165064 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255065 TestLoadTimingNotReused(load_timing_info,
5066 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5067
bnc691fda62016-08-12 00:43:165068 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525069 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465070
tbansal2ecbbc72016-10-06 17:15:475071 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465072 EXPECT_TRUE(response->headers->IsKeepAlive());
5073 EXPECT_EQ(200, response->headers->response_code());
5074 EXPECT_EQ(100, response->headers->GetContentLength());
5075 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5076
5077 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525078 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465079}
5080
[email protected]7642b5ae2010-09-01 20:55:175081// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015082TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275083 HttpRequestInfo request;
5084 request.method = "GET";
bncce36dca22015-04-21 22:11:235085 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105086 request.traffic_annotation =
5087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275088
[email protected]7642b5ae2010-09-01 20:55:175089 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595090 session_deps_.proxy_resolution_service =
5091 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515092 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075093 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175095
bncce36dca22015-04-21 22:11:235096 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415097 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455098 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415099 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175100
bnc42331402016-07-25 13:36:155101 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415102 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175103 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415104 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175105 };
5106
rch8e6c6c42015-05-01 14:05:135107 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5108 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075109 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175110
[email protected]8ddf8322012-02-23 18:08:065111 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365112 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175114
[email protected]49639fa2011-12-20 23:22:415115 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175116
bnc691fda62016-08-12 00:43:165117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505118
bnc691fda62016-08-12 00:43:165119 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175121
5122 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015123 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175124
[email protected]58e32bb2013-01-21 18:23:255125 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165126 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255127 TestLoadTimingNotReused(load_timing_info,
5128 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5129
bnc691fda62016-08-12 00:43:165130 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525131 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475132 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525133 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025134 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175135
5136 std::string response_data;
bnc691fda62016-08-12 00:43:165137 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235138 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175139}
5140
[email protected]1c173852014-06-19 12:51:505141// Verifies that a session which races and wins against the owning transaction
5142// (completing prior to host resolution), doesn't fail the transaction.
5143// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015144TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505145 HttpRequestInfo request;
5146 request.method = "GET";
bncce36dca22015-04-21 22:11:235147 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105148 request.traffic_annotation =
5149 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505150
5151 // Configure SPDY proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595152 session_deps_.proxy_resolution_service =
5153 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515154 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505155 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505157
bncce36dca22015-04-21 22:11:235158 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415159 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455160 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415161 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505162
bnc42331402016-07-25 13:36:155163 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415164 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505165 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415166 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505167 };
5168
rch8e6c6c42015-05-01 14:05:135169 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5170 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505171 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5172
5173 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365174 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5176
5177 TestCompletionCallback callback1;
5178
bnc691fda62016-08-12 00:43:165179 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505180
5181 // Stall the hostname resolution begun by the transaction.
5182 session_deps_.host_resolver->set_synchronous_mode(false);
5183 session_deps_.host_resolver->set_ondemand_mode(true);
5184
bnc691fda62016-08-12 00:43:165185 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505187
5188 // Race a session to the proxy, which completes first.
5189 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045190 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5191 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505192 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525193 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505194
5195 // Unstall the resolution begun by the transaction.
5196 session_deps_.host_resolver->set_ondemand_mode(true);
5197 session_deps_.host_resolver->ResolveAllPending();
5198
5199 EXPECT_FALSE(callback1.have_result());
5200 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015201 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505202
bnc691fda62016-08-12 00:43:165203 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525204 ASSERT_TRUE(response);
5205 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025206 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505207
5208 std::string response_data;
bnc691fda62016-08-12 00:43:165209 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505210 EXPECT_EQ(kUploadData, response_data);
5211}
5212
[email protected]dc7bd1c52010-11-12 00:01:135213// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015214TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275215 HttpRequestInfo request;
5216 request.method = "GET";
bncce36dca22015-04-21 22:11:235217 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105218 request.traffic_annotation =
5219 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275220
[email protected]79cb5c12011-09-12 13:12:045221 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595222 session_deps_.proxy_resolution_service =
5223 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515224 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075225 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095226 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135227
[email protected]dc7bd1c52010-11-12 00:01:135228 // The first request will be a bare GET, the second request will be a
5229 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455230 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415231 SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485232 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385233 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135234 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465235 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135236 };
bncdf80d44fd2016-07-15 20:27:415237 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5238 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485239 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135240 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415241 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135242 };
5243
5244 // The first response is a 407 proxy authentication challenge, and the second
5245 // response will be a 200 response since the second request includes a valid
5246 // Authorization header.
5247 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465248 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135249 };
bnc42331402016-07-25 13:36:155250 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235251 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415252 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5253 SpdySerializedFrame body_authentication(
5254 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155255 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415256 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135257 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415258 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465259 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415260 CreateMockRead(resp_data, 4),
5261 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135262 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135263 };
5264
rch8e6c6c42015-05-01 14:05:135265 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5266 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075267 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135268
[email protected]8ddf8322012-02-23 18:08:065269 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365270 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135272
[email protected]49639fa2011-12-20 23:22:415273 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135274
bnc691fda62016-08-12 00:43:165275 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135276
bnc691fda62016-08-12 00:43:165277 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015278 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135279
5280 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015281 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135282
bnc691fda62016-08-12 00:43:165283 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135284
wezca1070932016-05-26 20:30:525285 ASSERT_TRUE(response);
5286 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135287 EXPECT_EQ(407, response->headers->response_code());
5288 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435289 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135290
[email protected]49639fa2011-12-20 23:22:415291 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135292
bnc691fda62016-08-12 00:43:165293 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015294 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135295
5296 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015297 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135298
bnc691fda62016-08-12 00:43:165299 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135300
wezca1070932016-05-26 20:30:525301 ASSERT_TRUE(response_restart);
5302 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135303 EXPECT_EQ(200, response_restart->headers->response_code());
5304 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525305 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135306}
5307
[email protected]d9da5fe2010-10-13 22:37:165308// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015309TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275310 HttpRequestInfo request;
5311 request.method = "GET";
bncce36dca22015-04-21 22:11:235312 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105313 request.traffic_annotation =
5314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275315
[email protected]d9da5fe2010-10-13 22:37:165316 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595317 session_deps_.proxy_resolution_service =
5318 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515319 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075320 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165322
bnc691fda62016-08-12 00:43:165323 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165324
bncce36dca22015-04-21 22:11:235325 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415326 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235327 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5328 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165329
bncce36dca22015-04-21 22:11:235330 const char get[] =
5331 "GET / HTTP/1.1\r\n"
5332 "Host: www.example.org\r\n"
5333 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415334 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195335 spdy_util_.ConstructSpdyDataFrame(1, get, false));
bnc42331402016-07-25 13:36:155336 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165337 const char resp[] = "HTTP/1.1 200 OK\r\n"
5338 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415339 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195340 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
bncdf80d44fd2016-07-15 20:27:415341 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195342 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
bncdf80d44fd2016-07-15 20:27:415343 SpdySerializedFrame window_update(
5344 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045345
5346 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415347 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5348 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045349 };
5350
[email protected]d9da5fe2010-10-13 22:37:165351 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415352 CreateMockRead(conn_resp, 1, ASYNC),
5353 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5354 CreateMockRead(wrapped_body, 4, ASYNC),
5355 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135356 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165357 };
5358
rch8e6c6c42015-05-01 14:05:135359 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5360 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075361 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165362
[email protected]8ddf8322012-02-23 18:08:065363 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365364 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065366 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165368
[email protected]49639fa2011-12-20 23:22:415369 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165370
bnc691fda62016-08-12 00:43:165371 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165373
5374 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015375 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165376
[email protected]58e32bb2013-01-21 18:23:255377 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165378 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255379 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5380
bnc691fda62016-08-12 00:43:165381 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525382 ASSERT_TRUE(response);
5383 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165384 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5385
5386 std::string response_data;
bnc691fda62016-08-12 00:43:165387 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165388 EXPECT_EQ("1234567890", response_data);
5389}
5390
5391// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015392TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5393 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385394
[email protected]cb9bf6ca2011-01-28 13:15:275395 HttpRequestInfo request;
5396 request.method = "GET";
bncce36dca22015-04-21 22:11:235397 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105398 request.traffic_annotation =
5399 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275400
[email protected]d9da5fe2010-10-13 22:37:165401 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595402 session_deps_.proxy_resolution_service =
5403 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515404 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075405 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095406 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165407
bnc691fda62016-08-12 00:43:165408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165409
bncce36dca22015-04-21 22:11:235410 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415411 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235412 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5413 // fetch https://www.example.org/ via SPDY
5414 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415415 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495416 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415417 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155418 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415419 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155420 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415421 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025422 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415423 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5424 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025425 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415426 SpdySerializedFrame window_update_get_resp(
5427 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5428 SpdySerializedFrame window_update_body(
5429 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045430
5431 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415432 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5433 CreateMockWrite(window_update_get_resp, 6),
5434 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045435 };
5436
[email protected]d9da5fe2010-10-13 22:37:165437 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415438 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095439 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415440 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5441 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135442 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165443 };
5444
rch32320842015-05-16 15:57:095445 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5446 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075447 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165448
[email protected]8ddf8322012-02-23 18:08:065449 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365450 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075451 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065452 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365453 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165455
[email protected]49639fa2011-12-20 23:22:415456 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165457
bnc691fda62016-08-12 00:43:165458 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165460
rch32320842015-05-16 15:57:095461 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555462 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095463 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595464 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165465 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015466 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165467
[email protected]58e32bb2013-01-21 18:23:255468 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165469 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255470 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5471
bnc691fda62016-08-12 00:43:165472 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525473 ASSERT_TRUE(response);
5474 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025475 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165476
5477 std::string response_data;
bnc691fda62016-08-12 00:43:165478 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235479 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165480}
5481
5482// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015483TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275484 HttpRequestInfo request;
5485 request.method = "GET";
bncce36dca22015-04-21 22:11:235486 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105487 request.traffic_annotation =
5488 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275489
[email protected]d9da5fe2010-10-13 22:37:165490 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595491 session_deps_.proxy_resolution_service =
5492 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515493 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075494 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165496
bnc691fda62016-08-12 00:43:165497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165498
bncce36dca22015-04-21 22:11:235499 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415500 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235501 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415502 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085503 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165504
5505 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415506 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165507 };
5508
bnc42331402016-07-25 13:36:155509 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415510 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165511 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415512 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165513 };
5514
rch8e6c6c42015-05-01 14:05:135515 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5516 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075517 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165518
[email protected]8ddf8322012-02-23 18:08:065519 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365520 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075521 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065522 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365523 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165525
[email protected]49639fa2011-12-20 23:22:415526 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165527
bnc691fda62016-08-12 00:43:165528 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165530
5531 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015532 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165533
ttuttle960fcbf2016-04-19 13:26:325534 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165535}
5536
[email protected]f6c63db52013-02-02 00:35:225537// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5538// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015539TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225540 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5541 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595542 session_deps_.proxy_resolution_service =
5543 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515544 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075545 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095546 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505547 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225548
5549 HttpRequestInfo request1;
5550 request1.method = "GET";
bncce36dca22015-04-21 22:11:235551 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225552 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105553 request1.traffic_annotation =
5554 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225555
5556 HttpRequestInfo request2;
5557 request2.method = "GET";
bncce36dca22015-04-21 22:11:235558 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225559 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105560 request2.traffic_annotation =
5561 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225562
bncce36dca22015-04-21 22:11:235563 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415564 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235565 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155566 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225567
bncce36dca22015-04-21 22:11:235568 // Fetch https://www.example.org/ via HTTP.
5569 const char get1[] =
5570 "GET / HTTP/1.1\r\n"
5571 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225572 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415573 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195574 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225575 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5576 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415577 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195578 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415579 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195580 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415581 SpdySerializedFrame window_update(
5582 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225583
bncce36dca22015-04-21 22:11:235584 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295585 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275586 connect2_block[kHttp2MethodHeader] = "CONNECT";
5587 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155588 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5589 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395590
bnc42331402016-07-25 13:36:155591 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225592
bncce36dca22015-04-21 22:11:235593 // Fetch https://mail.example.org/ via HTTP.
5594 const char get2[] =
5595 "GET / HTTP/1.1\r\n"
5596 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225597 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415598 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195599 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225600 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5601 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415602 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195603 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
bncdf80d44fd2016-07-15 20:27:415604 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195605 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225606
5607 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415608 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5609 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225610 };
5611
5612 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415613 CreateMockRead(conn_resp1, 1, ASYNC),
5614 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5615 CreateMockRead(wrapped_body1, 4, ASYNC),
5616 CreateMockRead(conn_resp2, 6, ASYNC),
5617 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5618 CreateMockRead(wrapped_body2, 9, ASYNC),
5619 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225620 };
5621
mmenke11eb5152015-06-09 14:50:505622 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5623 arraysize(spdy_writes));
5624 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225625
5626 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365627 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225629 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225631 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225633
5634 TestCompletionCallback callback;
5635
bnc691fda62016-08-12 00:43:165636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205637 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015638 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225639
5640 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165641 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225642 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5643
bnc691fda62016-08-12 00:43:165644 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525645 ASSERT_TRUE(response);
5646 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225647 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5648
5649 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295650 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165651 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505652 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225653
bnc691fda62016-08-12 00:43:165654 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205655 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015656 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225657
5658 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165659 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225660 // Even though the SPDY connection is reused, a new tunnelled connection has
5661 // to be created, so the socket's load timing looks like a fresh connection.
5662 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5663
5664 // The requests should have different IDs, since they each are using their own
5665 // separate stream.
5666 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5667
bnc691fda62016-08-12 00:43:165668 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505669 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225670}
5671
5672// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5673// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015674TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225675 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5676 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595677 session_deps_.proxy_resolution_service =
5678 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515679 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075680 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095681 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505682 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225683
5684 HttpRequestInfo request1;
5685 request1.method = "GET";
bncce36dca22015-04-21 22:11:235686 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225687 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105688 request1.traffic_annotation =
5689 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225690
5691 HttpRequestInfo request2;
5692 request2.method = "GET";
bncce36dca22015-04-21 22:11:235693 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225694 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105695 request2.traffic_annotation =
5696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225697
bncce36dca22015-04-21 22:11:235698 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415699 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235700 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155701 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225702
bncce36dca22015-04-21 22:11:235703 // Fetch https://www.example.org/ via HTTP.
5704 const char get1[] =
5705 "GET / HTTP/1.1\r\n"
5706 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225707 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415708 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195709 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225710 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5711 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415712 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195713 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415714 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195715 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415716 SpdySerializedFrame window_update(
5717 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225718
bncce36dca22015-04-21 22:11:235719 // Fetch https://www.example.org/2 via HTTP.
5720 const char get2[] =
5721 "GET /2 HTTP/1.1\r\n"
5722 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225723 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415724 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195725 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225726 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5727 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415728 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195729 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
bncdf80d44fd2016-07-15 20:27:415730 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195731 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225732
5733 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415734 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5735 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225736 };
5737
5738 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415739 CreateMockRead(conn_resp1, 1, ASYNC),
5740 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465741 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415742 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465743 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415744 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225745 };
5746
mmenke11eb5152015-06-09 14:50:505747 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5748 arraysize(spdy_writes));
5749 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225750
5751 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365752 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225754 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225756
5757 TestCompletionCallback callback;
5758
bnc87dcefc2017-05-25 12:47:585759 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195760 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205761 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225763
5764 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015765 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225766
5767 LoadTimingInfo load_timing_info;
5768 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5769 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5770
5771 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525772 ASSERT_TRUE(response);
5773 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225774 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5775
5776 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295777 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505778 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225779 trans.reset();
5780
bnc87dcefc2017-05-25 12:47:585781 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205783 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225785
[email protected]f6c63db52013-02-02 00:35:225786 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015787 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225788
5789 LoadTimingInfo load_timing_info2;
5790 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5791 TestLoadTimingReused(load_timing_info2);
5792
5793 // The requests should have the same ID.
5794 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5795
[email protected]90499482013-06-01 00:39:505796 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225797}
5798
5799// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5800// Proxy to different servers.
bncd16676a2016-07-20 16:23:015801TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225802 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595803 session_deps_.proxy_resolution_service =
5804 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515805 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095807 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505808 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225809
5810 HttpRequestInfo request1;
5811 request1.method = "GET";
bncce36dca22015-04-21 22:11:235812 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225813 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105814 request1.traffic_annotation =
5815 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225816
5817 HttpRequestInfo request2;
5818 request2.method = "GET";
bncce36dca22015-04-21 22:11:235819 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225820 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105821 request2.traffic_annotation =
5822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225823
bncce36dca22015-04-21 22:11:235824 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265825 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235826 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415827 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155828 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5829 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Bence Békyd74f4382018-02-20 18:26:195830 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385831 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225832
bncce36dca22015-04-21 22:11:235833 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265834 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235835 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415836 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155837 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5838 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
Bence Békyd74f4382018-02-20 18:26:195839 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225840
5841 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415842 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225843 };
5844
5845 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415846 CreateMockRead(get_resp1, 1, ASYNC),
5847 CreateMockRead(body1, 2, ASYNC),
5848 CreateMockRead(get_resp2, 4, ASYNC),
5849 CreateMockRead(body2, 5, ASYNC),
5850 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225851 };
5852
mmenke11eb5152015-06-09 14:50:505853 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5854 arraysize(spdy_writes));
5855 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225856
5857 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365858 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505859 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225860
5861 TestCompletionCallback callback;
5862
bnc87dcefc2017-05-25 12:47:585863 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195864 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205865 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015866 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225867
5868 LoadTimingInfo load_timing_info;
5869 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5870 TestLoadTimingNotReused(load_timing_info,
5871 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5872
5873 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525874 ASSERT_TRUE(response);
5875 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025876 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225877
5878 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295879 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505880 rv = trans->Read(buf.get(), 256, callback.callback());
5881 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225882 // Delete the first request, so the second one can reuse the socket.
5883 trans.reset();
5884
bnc691fda62016-08-12 00:43:165885 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205886 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015887 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225888
5889 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165890 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225891 TestLoadTimingReused(load_timing_info2);
5892
5893 // The requests should have the same ID.
5894 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5895
bnc691fda62016-08-12 00:43:165896 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505897 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225898}
5899
[email protected]2df19bb2010-08-25 20:13:465900// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015901TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465902 HttpRequestInfo request;
5903 request.method = "GET";
bncce36dca22015-04-21 22:11:235904 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465905 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295906 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:105907 request.traffic_annotation =
5908 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465909
[email protected]79cb5c12011-09-12 13:12:045910 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595911 session_deps_.proxy_resolution_service =
5912 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515913 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075914 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275916
[email protected]2df19bb2010-08-25 20:13:465917 // Since we have proxy, should use full url
5918 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165919 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5920 "Host: www.example.org\r\n"
5921 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465922
bnc691fda62016-08-12 00:43:165923 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235924 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165925 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5926 "Host: www.example.org\r\n"
5927 "Proxy-Connection: keep-alive\r\n"
5928 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465929 };
5930
5931 // The proxy responds to the GET with a 407, using a persistent
5932 // connection.
5933 MockRead data_reads1[] = {
5934 // No credentials.
5935 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5936 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5937 MockRead("Proxy-Connection: keep-alive\r\n"),
5938 MockRead("Content-Length: 0\r\n\r\n"),
5939
5940 MockRead("HTTP/1.1 200 OK\r\n"),
5941 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5942 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065943 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465944 };
5945
5946 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5947 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075948 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065949 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075950 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465951
[email protected]49639fa2011-12-20 23:22:415952 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465953
bnc691fda62016-08-12 00:43:165954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505955
bnc691fda62016-08-12 00:43:165956 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465958
5959 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015960 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465961
[email protected]58e32bb2013-01-21 18:23:255962 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165963 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255964 TestLoadTimingNotReused(load_timing_info,
5965 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5966
bnc691fda62016-08-12 00:43:165967 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525968 ASSERT_TRUE(response);
5969 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465970 EXPECT_EQ(407, response->headers->response_code());
5971 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435972 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465973
[email protected]49639fa2011-12-20 23:22:415974 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465975
bnc691fda62016-08-12 00:43:165976 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465978
5979 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015980 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465981
[email protected]58e32bb2013-01-21 18:23:255982 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165983 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255984 // Retrying with HTTP AUTH is considered to be reusing a socket.
5985 TestLoadTimingReused(load_timing_info);
5986
bnc691fda62016-08-12 00:43:165987 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525988 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465989
5990 EXPECT_TRUE(response->headers->IsKeepAlive());
5991 EXPECT_EQ(200, response->headers->response_code());
5992 EXPECT_EQ(100, response->headers->GetContentLength());
5993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5994
5995 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525996 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465997}
5998
[email protected]23e482282013-06-14 16:08:025999void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086000 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426001 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086002 request.method = "GET";
bncce36dca22015-04-21 22:11:236003 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106004 request.traffic_annotation =
6005 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086006
[email protected]cb9bf6ca2011-01-28 13:15:276007 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596008 session_deps_.proxy_resolution_service =
6009 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096010 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276011
[email protected]c744cf22009-02-27 07:28:086012 // Since we have proxy, should try to establish tunnel.
6013 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176014 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6015 "Host: www.example.org:443\r\n"
6016 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086017 };
6018
6019 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236020 status, MockRead("Content-Length: 10\r\n\r\n"),
6021 // No response body because the test stops reading here.
6022 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086023 };
6024
[email protected]31a2bfe2010-02-09 08:03:396025 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6026 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076027 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086028
[email protected]49639fa2011-12-20 23:22:416029 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086030
bnc691fda62016-08-12 00:43:166031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506032
tfarina42834112016-09-22 13:38:206033 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086035
6036 rv = callback.WaitForResult();
6037 EXPECT_EQ(expected_status, rv);
6038}
6039
[email protected]23e482282013-06-14 16:08:026040void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236041 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086042 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426043 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086044}
6045
bncd16676a2016-07-20 16:23:016046TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086047 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6048}
6049
bncd16676a2016-07-20 16:23:016050TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086051 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6052}
6053
bncd16676a2016-07-20 16:23:016054TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086055 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6056}
6057
bncd16676a2016-07-20 16:23:016058TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086059 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6060}
6061
bncd16676a2016-07-20 16:23:016062TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086063 ConnectStatusHelper(
6064 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6065}
6066
bncd16676a2016-07-20 16:23:016067TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086068 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6069}
6070
bncd16676a2016-07-20 16:23:016071TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086072 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6073}
6074
bncd16676a2016-07-20 16:23:016075TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086076 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6077}
6078
bncd16676a2016-07-20 16:23:016079TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086080 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6081}
6082
bncd16676a2016-07-20 16:23:016083TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086084 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6085}
6086
bncd16676a2016-07-20 16:23:016087TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086088 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6089}
6090
bncd16676a2016-07-20 16:23:016091TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086092 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6093}
6094
bncd16676a2016-07-20 16:23:016095TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086096 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6097}
6098
bncd16676a2016-07-20 16:23:016099TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086100 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6101}
6102
bncd16676a2016-07-20 16:23:016103TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086104 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6105}
6106
bncd16676a2016-07-20 16:23:016107TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086108 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6109}
6110
bncd16676a2016-07-20 16:23:016111TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376112 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6113}
6114
bncd16676a2016-07-20 16:23:016115TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086116 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6117}
6118
bncd16676a2016-07-20 16:23:016119TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086120 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6121}
6122
bncd16676a2016-07-20 16:23:016123TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086124 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6125}
6126
bncd16676a2016-07-20 16:23:016127TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086128 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6129}
6130
bncd16676a2016-07-20 16:23:016131TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086132 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6133}
6134
bncd16676a2016-07-20 16:23:016135TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086136 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6137}
6138
bncd16676a2016-07-20 16:23:016139TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086140 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6141}
6142
bncd16676a2016-07-20 16:23:016143TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086144 ConnectStatusHelperWithExpectedStatus(
6145 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546146 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086147}
6148
bncd16676a2016-07-20 16:23:016149TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086150 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6151}
6152
bncd16676a2016-07-20 16:23:016153TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086154 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6155}
6156
bncd16676a2016-07-20 16:23:016157TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086158 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6159}
6160
bncd16676a2016-07-20 16:23:016161TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086162 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6163}
6164
bncd16676a2016-07-20 16:23:016165TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086166 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6167}
6168
bncd16676a2016-07-20 16:23:016169TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086170 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6171}
6172
bncd16676a2016-07-20 16:23:016173TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086174 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6175}
6176
bncd16676a2016-07-20 16:23:016177TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086178 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6179}
6180
bncd16676a2016-07-20 16:23:016181TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086182 ConnectStatusHelper(
6183 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6184}
6185
bncd16676a2016-07-20 16:23:016186TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086187 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6188}
6189
bncd16676a2016-07-20 16:23:016190TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086191 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6192}
6193
bncd16676a2016-07-20 16:23:016194TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086195 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6196}
6197
bncd16676a2016-07-20 16:23:016198TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086199 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6200}
6201
bncd16676a2016-07-20 16:23:016202TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086203 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6204}
6205
bncd16676a2016-07-20 16:23:016206TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086207 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6208}
6209
bncd16676a2016-07-20 16:23:016210TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086211 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6212}
6213
[email protected]038e9a32008-10-08 22:40:166214// Test the flow when both the proxy server AND origin server require
6215// authentication. Again, this uses basic auth for both since that is
6216// the simplest to mock.
bncd16676a2016-07-20 16:23:016217TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276218 HttpRequestInfo request;
6219 request.method = "GET";
bncce36dca22015-04-21 22:11:236220 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106221 request.traffic_annotation =
6222 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276223
[email protected]038e9a32008-10-08 22:40:166224 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596225 session_deps_.proxy_resolution_service =
6226 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076228
bnc691fda62016-08-12 00:43:166229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166230
[email protected]f9ee6b52008-11-08 06:46:236231 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236232 MockWrite(
6233 "GET http://www.example.org/ HTTP/1.1\r\n"
6234 "Host: www.example.org\r\n"
6235 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236236 };
6237
[email protected]038e9a32008-10-08 22:40:166238 MockRead data_reads1[] = {
6239 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6240 // Give a couple authenticate options (only the middle one is actually
6241 // supported).
[email protected]22927ad2009-09-21 19:56:196242 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166243 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6244 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6245 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6246 // Large content-length -- won't matter, as connection will be reset.
6247 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066248 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166249 };
6250
bnc691fda62016-08-12 00:43:166251 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166252 // request we should be issuing -- the final header line contains the
6253 // proxy's credentials.
6254 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236255 MockWrite(
6256 "GET http://www.example.org/ HTTP/1.1\r\n"
6257 "Host: www.example.org\r\n"
6258 "Proxy-Connection: keep-alive\r\n"
6259 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166260 };
6261
6262 // Now the proxy server lets the request pass through to origin server.
6263 // The origin server responds with a 401.
6264 MockRead data_reads2[] = {
6265 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6266 // Note: We are using the same realm-name as the proxy server. This is
6267 // completely valid, as realms are unique across hosts.
6268 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6269 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6270 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066271 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166272 };
6273
bnc691fda62016-08-12 00:43:166274 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166275 // the credentials for both the proxy and origin server.
6276 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236277 MockWrite(
6278 "GET http://www.example.org/ HTTP/1.1\r\n"
6279 "Host: www.example.org\r\n"
6280 "Proxy-Connection: keep-alive\r\n"
6281 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6282 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166283 };
6284
6285 // Lastly we get the desired content.
6286 MockRead data_reads3[] = {
6287 MockRead("HTTP/1.0 200 OK\r\n"),
6288 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6289 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066290 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166291 };
6292
[email protected]31a2bfe2010-02-09 08:03:396293 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6294 data_writes1, arraysize(data_writes1));
6295 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6296 data_writes2, arraysize(data_writes2));
6297 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6298 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076299 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6300 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6301 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166302
[email protected]49639fa2011-12-20 23:22:416303 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166304
tfarina42834112016-09-22 13:38:206305 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016306 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166307
6308 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016309 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166310
bnc691fda62016-08-12 00:43:166311 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526312 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046313 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166314
[email protected]49639fa2011-12-20 23:22:416315 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166316
bnc691fda62016-08-12 00:43:166317 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166319
6320 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016321 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166322
bnc691fda62016-08-12 00:43:166323 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526324 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046325 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166326
[email protected]49639fa2011-12-20 23:22:416327 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166328
bnc691fda62016-08-12 00:43:166329 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6330 callback3.callback());
robpercival214763f2016-07-01 23:27:016331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166332
6333 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016334 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166335
bnc691fda62016-08-12 00:43:166336 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526337 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166338 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166339}
[email protected]4ddaf2502008-10-23 18:26:196340
[email protected]ea9dc9a2009-09-05 00:43:326341// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6342// can't hook into its internals to cause it to generate predictable NTLM
6343// authorization headers.
6344#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376345// The NTLM authentication unit tests are based on known test data from the
6346// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6347// flow rather than the implementation of the NTLM protocol. See net/ntlm
6348// for the implementation and testing of the protocol.
6349//
6350// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296351
6352// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556353TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426354 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246355 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556356 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106357 request.traffic_annotation =
6358 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546359
6360 // Ensure load is not disrupted by flags which suppress behaviour specific
6361 // to other auth schemes.
6362 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246363
Zentaro Kavanagh6ccee512017-09-28 18:34:096364 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6365 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096366 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276367
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376368 // Generate the NTLM messages based on known test data.
6369 std::string negotiate_msg;
6370 std::string challenge_msg;
6371 std::string authenticate_msg;
6372 base::Base64Encode(
6373 base::StringPiece(
6374 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6375 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6376 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556377 base::Base64Encode(
6378 base::StringPiece(
6379 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6380 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6381 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376382 base::Base64Encode(
6383 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096384 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556385 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6386 arraysize(
6387 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376388 &authenticate_msg);
6389
[email protected]3f918782009-02-28 01:29:246390 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556391 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6392 "Host: server\r\n"
6393 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246394 };
6395
6396 MockRead data_reads1[] = {
6397 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046398 // Negotiate and NTLM are often requested together. However, we only want
6399 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6400 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246401 MockRead("WWW-Authenticate: NTLM\r\n"),
6402 MockRead("Connection: close\r\n"),
6403 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366404 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246405 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246406 };
6407
6408 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166409 // After restarting with a null identity, this is the
6410 // request we should be issuing -- the final header line contains a Type
6411 // 1 message.
6412 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556413 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166414 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376415 "Authorization: NTLM "),
6416 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246417
bnc691fda62016-08-12 00:43:166418 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376419 // (using correct credentials). The second request continues on the
6420 // same connection.
bnc691fda62016-08-12 00:43:166421 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556422 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166423 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376424 "Authorization: NTLM "),
6425 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246426 };
6427
6428 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026429 // The origin server responds with a Type 2 message.
6430 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376431 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6432 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026433 MockRead("Content-Type: text/html\r\n\r\n"),
6434 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246435
Bence Béky1e4ef192017-09-18 19:58:026436 // Lastly we get the desired content.
6437 MockRead("HTTP/1.1 200 OK\r\n"),
6438 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6439 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246440 };
6441
[email protected]31a2bfe2010-02-09 08:03:396442 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6443 data_writes1, arraysize(data_writes1));
6444 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6445 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076446 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6447 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246448
Bence Béky83eb3512017-09-05 12:56:096449 SSLSocketDataProvider ssl1(ASYNC, OK);
6450 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6451 SSLSocketDataProvider ssl2(ASYNC, OK);
6452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6453
[email protected]49639fa2011-12-20 23:22:416454 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246455
bnc691fda62016-08-12 00:43:166456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506457
tfarina42834112016-09-22 13:38:206458 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246460
6461 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016462 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246463
bnc691fda62016-08-12 00:43:166464 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226465
bnc691fda62016-08-12 00:43:166466 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526467 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046468 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246469
[email protected]49639fa2011-12-20 23:22:416470 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256471
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376472 rv = trans.RestartWithAuth(
6473 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6474 callback2.callback());
robpercival214763f2016-07-01 23:27:016475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256476
6477 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016478 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256479
bnc691fda62016-08-12 00:43:166480 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256481
bnc691fda62016-08-12 00:43:166482 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526483 ASSERT_TRUE(response);
6484 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256485
[email protected]49639fa2011-12-20 23:22:416486 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246487
bnc691fda62016-08-12 00:43:166488 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246490
[email protected]0757e7702009-03-27 04:00:226491 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016492 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246493
bnc691fda62016-08-12 00:43:166494 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526495 ASSERT_TRUE(response);
6496 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026497 EXPECT_EQ(14, response->headers->GetContentLength());
6498
6499 std::string response_data;
6500 rv = ReadTransaction(&trans, &response_data);
6501 EXPECT_THAT(rv, IsOk());
6502 EXPECT_EQ("Please Login\r\n", response_data);
6503
6504 EXPECT_TRUE(data1.AllReadDataConsumed());
6505 EXPECT_TRUE(data1.AllWriteDataConsumed());
6506 EXPECT_TRUE(data2.AllReadDataConsumed());
6507 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246508}
6509
[email protected]385a4672009-03-11 22:21:296510// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556511TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426512 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296513 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556514 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106515 request.traffic_annotation =
6516 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296517
Zentaro Kavanagh6ccee512017-09-28 18:34:096518 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6519 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276521
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376522 // Generate the NTLM messages based on known test data.
6523 std::string negotiate_msg;
6524 std::string challenge_msg;
6525 std::string authenticate_msg;
6526 base::Base64Encode(
6527 base::StringPiece(
6528 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6529 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6530 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556531 base::Base64Encode(
6532 base::StringPiece(
6533 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6534 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6535 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376536 base::Base64Encode(
6537 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096538 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556539 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6540 arraysize(
6541 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376542 &authenticate_msg);
6543
6544 // The authenticate message when |kWrongPassword| is sent.
6545 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556546 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6547 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6548 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6549 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6550 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6551 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376552
Zentaro Kavanagh1890a3d2018-01-29 19:52:556553 // Sanity check that it's the same length as the correct authenticate message
6554 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376555 ASSERT_EQ(authenticate_msg.length(),
6556 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556557 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376558
[email protected]385a4672009-03-11 22:21:296559 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556560 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6561 "Host: server\r\n"
6562 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296563 };
6564
6565 MockRead data_reads1[] = {
6566 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046567 // Negotiate and NTLM are often requested together. However, we only want
6568 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6569 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296570 MockRead("WWW-Authenticate: NTLM\r\n"),
6571 MockRead("Connection: close\r\n"),
6572 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366573 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296574 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296575 };
6576
6577 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166578 // After restarting with a null identity, this is the
6579 // request we should be issuing -- the final header line contains a Type
6580 // 1 message.
6581 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556582 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166583 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376584 "Authorization: NTLM "),
6585 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296586
bnc691fda62016-08-12 00:43:166587 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376588 // (using incorrect credentials). The second request continues on the
6589 // same connection.
bnc691fda62016-08-12 00:43:166590 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556591 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166592 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376593 "Authorization: NTLM "),
6594 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296595 };
6596
6597 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376598 // The origin server responds with a Type 2 message.
6599 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6600 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6601 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6602 MockRead("Content-Type: text/html\r\n\r\n"),
6603 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296604
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376605 // Wrong password.
6606 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6607 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6608 MockRead("Content-Length: 42\r\n"),
6609 MockRead("Content-Type: text/html\r\n\r\n"),
6610 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296611 };
6612
6613 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166614 // After restarting with a null identity, this is the
6615 // request we should be issuing -- the final header line contains a Type
6616 // 1 message.
6617 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556618 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166619 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376620 "Authorization: NTLM "),
6621 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296622
bnc691fda62016-08-12 00:43:166623 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6624 // (the credentials for the origin server). The second request continues
6625 // on the same connection.
6626 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556627 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166628 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376629 "Authorization: NTLM "),
6630 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296631 };
6632
6633 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026634 // The origin server responds with a Type 2 message.
6635 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376636 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6637 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026638 MockRead("Content-Type: text/html\r\n\r\n"),
6639 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296640
Bence Béky1e4ef192017-09-18 19:58:026641 // Lastly we get the desired content.
6642 MockRead("HTTP/1.1 200 OK\r\n"),
6643 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6644 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296645 };
6646
[email protected]31a2bfe2010-02-09 08:03:396647 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6648 data_writes1, arraysize(data_writes1));
6649 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6650 data_writes2, arraysize(data_writes2));
6651 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6652 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076653 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6654 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6655 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296656
Bence Béky83eb3512017-09-05 12:56:096657 SSLSocketDataProvider ssl1(ASYNC, OK);
6658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6659 SSLSocketDataProvider ssl2(ASYNC, OK);
6660 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6661 SSLSocketDataProvider ssl3(ASYNC, OK);
6662 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6663
[email protected]49639fa2011-12-20 23:22:416664 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296665
bnc691fda62016-08-12 00:43:166666 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506667
tfarina42834112016-09-22 13:38:206668 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296670
6671 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016672 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296673
bnc691fda62016-08-12 00:43:166674 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296675
bnc691fda62016-08-12 00:43:166676 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526677 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046678 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296679
[email protected]49639fa2011-12-20 23:22:416680 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296681
[email protected]0757e7702009-03-27 04:00:226682 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376683 rv = trans.RestartWithAuth(
6684 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6685 callback2.callback());
robpercival214763f2016-07-01 23:27:016686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296687
[email protected]10af5fe72011-01-31 16:17:256688 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016689 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296690
bnc691fda62016-08-12 00:43:166691 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416692 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166693 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256695 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016696 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166697 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226698
bnc691fda62016-08-12 00:43:166699 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526700 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046701 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226702
[email protected]49639fa2011-12-20 23:22:416703 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226704
6705 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376706 rv = trans.RestartWithAuth(
6707 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6708 callback4.callback());
robpercival214763f2016-07-01 23:27:016709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256710
6711 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016712 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256713
bnc691fda62016-08-12 00:43:166714 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256715
[email protected]49639fa2011-12-20 23:22:416716 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256717
6718 // One more roundtrip
bnc691fda62016-08-12 00:43:166719 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226721
6722 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016723 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226724
bnc691fda62016-08-12 00:43:166725 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526726 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026727 EXPECT_EQ(14, response->headers->GetContentLength());
6728
6729 std::string response_data;
6730 rv = ReadTransaction(&trans, &response_data);
6731 EXPECT_THAT(rv, IsOk());
6732 EXPECT_EQ("Please Login\r\n", response_data);
6733
6734 EXPECT_TRUE(data1.AllReadDataConsumed());
6735 EXPECT_TRUE(data1.AllWriteDataConsumed());
6736 EXPECT_TRUE(data2.AllReadDataConsumed());
6737 EXPECT_TRUE(data2.AllWriteDataConsumed());
6738 EXPECT_TRUE(data3.AllReadDataConsumed());
6739 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296740}
Bence Béky83eb3512017-09-05 12:56:096741
Bence Béky3238f2e12017-09-22 22:44:496742// Server requests NTLM authentication, which is not supported over HTTP/2.
6743// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096744TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096745 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6746 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096747
Zentaro Kavanagh1890a3d2018-01-29 19:52:556748 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096749
6750 HttpRequestInfo request;
6751 request.method = "GET";
6752 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:106753 request.traffic_annotation =
6754 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096755
6756 // First request without credentials.
6757 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6758 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6759 1, std::move(request_headers0), LOWEST, true));
6760
6761 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276762 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096763 response_headers0["www-authenticate"] = "NTLM";
6764 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6765 1, std::move(response_headers0), true));
6766
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376767 // Stream 1 is closed.
6768 spdy_util_.UpdateWithStreamDestruction(1);
6769
6770 // Generate the NTLM messages based on known test data.
6771 std::string negotiate_msg;
6772 std::string challenge_msg;
6773 std::string authenticate_msg;
6774 base::Base64Encode(
6775 base::StringPiece(
6776 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6777 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6778 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556779 base::Base64Encode(
6780 base::StringPiece(
6781 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6782 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6783 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376784 base::Base64Encode(
6785 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096786 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556787 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6788 arraysize(
6789 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376790 &authenticate_msg);
6791
6792 // Retry with authorization header.
6793 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6794 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6795 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6796 3, std::move(request_headers1), LOWEST, true));
6797
6798 SpdySerializedFrame rst(
6799 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6800
Bence Béky3238f2e12017-09-22 22:44:496801 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6802 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096803
6804 // Retry yet again using HTTP/1.1.
6805 MockWrite writes1[] = {
6806 // After restarting with a null identity, this is the
6807 // request we should be issuing -- the final header line contains a Type
6808 // 1 message.
6809 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556810 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096811 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376812 "Authorization: NTLM "),
6813 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096814
6815 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6816 // (the credentials for the origin server). The second request continues
6817 // on the same connection.
6818 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556819 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096820 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376821 "Authorization: NTLM "),
6822 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096823 };
6824
6825 MockRead reads1[] = {
6826 // The origin server responds with a Type 2 message.
6827 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376828 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6829 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096830 MockRead("Content-Type: text/html\r\n\r\n"),
6831 MockRead("You are not authorized to view this page\r\n"),
6832
6833 // Lastly we get the desired content.
6834 MockRead("HTTP/1.1 200 OK\r\n"),
6835 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026836 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096837 };
6838 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6839 arraysize(writes0));
6840 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6841 arraysize(writes1));
6842 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6843 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6844
6845 SSLSocketDataProvider ssl0(ASYNC, OK);
6846 ssl0.next_proto = kProtoHTTP2;
6847 SSLSocketDataProvider ssl1(ASYNC, OK);
6848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6850
6851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6853
6854 TestCompletionCallback callback1;
6855 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6857
6858 rv = callback1.WaitForResult();
6859 EXPECT_THAT(rv, IsOk());
6860
6861 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6862
6863 const HttpResponseInfo* response = trans.GetResponseInfo();
6864 ASSERT_TRUE(response);
6865 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6866
6867 TestCompletionCallback callback2;
6868
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376869 rv = trans.RestartWithAuth(
6870 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6871 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6873
6874 rv = callback2.WaitForResult();
6875 EXPECT_THAT(rv, IsOk());
6876
6877 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6878
6879 response = trans.GetResponseInfo();
6880 ASSERT_TRUE(response);
6881 EXPECT_FALSE(response->auth_challenge);
6882
6883 TestCompletionCallback callback3;
6884
6885 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6886 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6887
6888 rv = callback3.WaitForResult();
6889 EXPECT_THAT(rv, IsOk());
6890
6891 response = trans.GetResponseInfo();
6892 ASSERT_TRUE(response);
6893 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026894 EXPECT_EQ(14, response->headers->GetContentLength());
6895
6896 std::string response_data;
6897 rv = ReadTransaction(&trans, &response_data);
6898 EXPECT_THAT(rv, IsOk());
6899 EXPECT_EQ("Please Login\r\n", response_data);
6900
6901 EXPECT_TRUE(data0.AllReadDataConsumed());
6902 EXPECT_TRUE(data0.AllWriteDataConsumed());
6903 EXPECT_TRUE(data1.AllReadDataConsumed());
6904 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096905}
[email protected]ea9dc9a2009-09-05 00:43:326906#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296907
[email protected]4ddaf2502008-10-23 18:26:196908// Test reading a server response which has only headers, and no body.
6909// After some maximum number of bytes is consumed, the transaction should
6910// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016911TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426912 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196913 request.method = "GET";
bncce36dca22015-04-21 22:11:236914 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106915 request.traffic_annotation =
6916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196917
danakj1fd259a02016-04-16 03:17:096918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276920
[email protected]b75b7b2f2009-10-06 00:54:536921 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436922 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536923 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196924
6925 MockRead data_reads[] = {
6926 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066927 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196928 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066929 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196930 };
[email protected]31a2bfe2010-02-09 08:03:396931 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076932 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196933
[email protected]49639fa2011-12-20 23:22:416934 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196935
tfarina42834112016-09-22 13:38:206936 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196938
6939 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016940 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196941}
[email protected]f4e426b2008-11-05 00:24:496942
6943// Make sure that we don't try to reuse a TCPClientSocket when failing to
6944// establish tunnel.
6945// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276947 HttpRequestInfo request;
6948 request.method = "GET";
bncce36dca22015-04-21 22:11:236949 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106950 request.traffic_annotation =
6951 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276952
[email protected]f4e426b2008-11-05 00:24:496953 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596954 session_deps_.proxy_resolution_service =
6955 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016956
danakj1fd259a02016-04-16 03:17:096957 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496958
bnc87dcefc2017-05-25 12:47:586959 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196960 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496961
[email protected]f4e426b2008-11-05 00:24:496962 // Since we have proxy, should try to establish tunnel.
6963 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176964 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6965 "Host: www.example.org:443\r\n"
6966 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496967 };
6968
[email protected]77848d12008-11-14 00:00:226969 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496970 // connection. Usually a proxy would return 501 (not implemented),
6971 // or 200 (tunnel established).
6972 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236973 MockRead("HTTP/1.1 404 Not Found\r\n"),
6974 MockRead("Content-Length: 10\r\n\r\n"),
6975 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496976 };
6977
[email protected]31a2bfe2010-02-09 08:03:396978 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6979 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076980 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496981
[email protected]49639fa2011-12-20 23:22:416982 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496983
tfarina42834112016-09-22 13:38:206984 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496986
6987 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016988 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496989
[email protected]b4404c02009-04-10 16:38:526990 // Empty the current queue. This is necessary because idle sockets are
6991 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556992 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526993
[email protected]f4e426b2008-11-05 00:24:496994 // We now check to make sure the TCPClientSocket was not added back to
6995 // the pool.
[email protected]90499482013-06-01 00:39:506996 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496997 trans.reset();
fdoray92e35a72016-06-10 15:54:556998 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496999 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507000 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497001}
[email protected]372d34a2008-11-05 21:30:517002
[email protected]1b157c02009-04-21 01:55:407003// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017004TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427005 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407006 request.method = "GET";
bncce36dca22015-04-21 22:11:237007 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107008 request.traffic_annotation =
7009 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407010
danakj1fd259a02016-04-16 03:17:097011 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277012
bnc691fda62016-08-12 00:43:167013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277014
[email protected]1b157c02009-04-21 01:55:407015 MockRead data_reads[] = {
7016 // A part of the response body is received with the response headers.
7017 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7018 // The rest of the response body is received in two parts.
7019 MockRead("lo"),
7020 MockRead(" world"),
7021 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067022 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407023 };
7024
[email protected]31a2bfe2010-02-09 08:03:397025 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077026 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407027
[email protected]49639fa2011-12-20 23:22:417028 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407029
tfarina42834112016-09-22 13:38:207030 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407032
7033 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017034 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407035
bnc691fda62016-08-12 00:43:167036 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527037 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407038
wezca1070932016-05-26 20:30:527039 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407040 std::string status_line = response->headers->GetStatusLine();
7041 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7042
[email protected]90499482013-06-01 00:39:507043 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407044
7045 std::string response_data;
bnc691fda62016-08-12 00:43:167046 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017047 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407048 EXPECT_EQ("hello world", response_data);
7049
7050 // Empty the current queue. This is necessary because idle sockets are
7051 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557052 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407053
7054 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507055 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407056}
7057
[email protected]76a505b2010-08-25 06:23:007058// Make sure that we recycle a SSL socket after reading all of the response
7059// body.
bncd16676a2016-07-20 16:23:017060TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007061 HttpRequestInfo request;
7062 request.method = "GET";
bncce36dca22015-04-21 22:11:237063 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107064 request.traffic_annotation =
7065 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007066
7067 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237068 MockWrite(
7069 "GET / HTTP/1.1\r\n"
7070 "Host: www.example.org\r\n"
7071 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007072 };
7073
7074 MockRead data_reads[] = {
7075 MockRead("HTTP/1.1 200 OK\r\n"),
7076 MockRead("Content-Length: 11\r\n\r\n"),
7077 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067078 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007079 };
7080
[email protected]8ddf8322012-02-23 18:08:067081 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077082 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007083
7084 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7085 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077086 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007087
[email protected]49639fa2011-12-20 23:22:417088 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007089
danakj1fd259a02016-04-16 03:17:097090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007092
tfarina42834112016-09-22 13:38:207093 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007094
robpercival214763f2016-07-01 23:27:017095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7096 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007097
bnc691fda62016-08-12 00:43:167098 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527099 ASSERT_TRUE(response);
7100 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007101 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7102
[email protected]90499482013-06-01 00:39:507103 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007104
7105 std::string response_data;
bnc691fda62016-08-12 00:43:167106 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017107 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007108 EXPECT_EQ("hello world", response_data);
7109
7110 // Empty the current queue. This is necessary because idle sockets are
7111 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557112 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007113
7114 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507115 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007116}
7117
7118// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7119// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017120TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007121 HttpRequestInfo request;
7122 request.method = "GET";
bncce36dca22015-04-21 22:11:237123 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107124 request.traffic_annotation =
7125 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007126
7127 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237128 MockWrite(
7129 "GET / HTTP/1.1\r\n"
7130 "Host: www.example.org\r\n"
7131 "Connection: keep-alive\r\n\r\n"),
7132 MockWrite(
7133 "GET / HTTP/1.1\r\n"
7134 "Host: www.example.org\r\n"
7135 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007136 };
7137
7138 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427139 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7140 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007141
[email protected]8ddf8322012-02-23 18:08:067142 SSLSocketDataProvider ssl(ASYNC, OK);
7143 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007146
7147 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7148 data_writes, arraysize(data_writes));
7149 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7150 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077151 session_deps_.socket_factory->AddSocketDataProvider(&data);
7152 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007153
[email protected]49639fa2011-12-20 23:22:417154 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007155
danakj1fd259a02016-04-16 03:17:097156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587157 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197158 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007159
tfarina42834112016-09-22 13:38:207160 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007161
robpercival214763f2016-07-01 23:27:017162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7163 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007164
7165 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527166 ASSERT_TRUE(response);
7167 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007168 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7169
[email protected]90499482013-06-01 00:39:507170 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007171
7172 std::string response_data;
7173 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017174 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007175 EXPECT_EQ("hello world", response_data);
7176
7177 // Empty the current queue. This is necessary because idle sockets are
7178 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557179 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007180
7181 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507182 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007183
7184 // Now start the second transaction, which should reuse the previous socket.
7185
bnc87dcefc2017-05-25 12:47:587186 trans =
Jeremy Roman0579ed62017-08-29 15:56:197187 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007188
tfarina42834112016-09-22 13:38:207189 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007190
robpercival214763f2016-07-01 23:27:017191 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7192 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007193
7194 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527195 ASSERT_TRUE(response);
7196 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007197 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7198
[email protected]90499482013-06-01 00:39:507199 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007200
7201 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017202 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007203 EXPECT_EQ("hello world", response_data);
7204
7205 // Empty the current queue. This is necessary because idle sockets are
7206 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557207 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007208
7209 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507210 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007211}
7212
maksim.sisov0adf8592016-07-15 06:25:567213// Grab a socket, use it, and put it back into the pool. Then, make
7214// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017215TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567216 HttpRequestInfo request;
7217 request.method = "GET";
7218 request.url = GURL("http://www.example.org/");
7219 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107220 request.traffic_annotation =
7221 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567222
7223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7224
bnc691fda62016-08-12 00:43:167225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567226
7227 MockRead data_reads[] = {
7228 // A part of the response body is received with the response headers.
7229 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7230 // The rest of the response body is received in two parts.
7231 MockRead("lo"), MockRead(" world"),
7232 MockRead("junk"), // Should not be read!!
7233 MockRead(SYNCHRONOUS, OK),
7234 };
7235
7236 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7237 session_deps_.socket_factory->AddSocketDataProvider(&data);
7238
7239 TestCompletionCallback callback;
7240
tfarina42834112016-09-22 13:38:207241 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7243
7244 EXPECT_THAT(callback.GetResult(rv), IsOk());
7245
bnc691fda62016-08-12 00:43:167246 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567247 ASSERT_TRUE(response);
7248 EXPECT_TRUE(response->headers);
7249 std::string status_line = response->headers->GetStatusLine();
7250 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7251
7252 // Make memory critical notification and ensure the transaction still has been
7253 // operating right.
7254 base::MemoryPressureListener::NotifyMemoryPressure(
7255 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7256 base::RunLoop().RunUntilIdle();
7257
7258 // Socket should not be flushed as long as it is not idle.
7259 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7260
7261 std::string response_data;
bnc691fda62016-08-12 00:43:167262 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567263 EXPECT_THAT(rv, IsOk());
7264 EXPECT_EQ("hello world", response_data);
7265
7266 // Empty the current queue. This is necessary because idle sockets are
7267 // added to the connection pool asynchronously with a PostTask.
7268 base::RunLoop().RunUntilIdle();
7269
7270 // We now check to make sure the socket was added back to the pool.
7271 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7272
7273 // Idle sockets should be flushed now.
7274 base::MemoryPressureListener::NotifyMemoryPressure(
7275 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7276 base::RunLoop().RunUntilIdle();
7277
7278 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7279}
7280
yucliu48f235d2018-01-11 00:59:557281// Disable idle socket closing on memory pressure.
7282// Grab a socket, use it, and put it back into the pool. Then, make
7283// low memory notification and ensure the socket pool is NOT flushed.
7284TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7285 HttpRequestInfo request;
7286 request.method = "GET";
7287 request.url = GURL("http://www.example.org/");
7288 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107289 request.traffic_annotation =
7290 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557291
7292 // Disable idle socket closing on memory pressure.
7293 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7294 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7295
7296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7297
7298 MockRead data_reads[] = {
7299 // A part of the response body is received with the response headers.
7300 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7301 // The rest of the response body is received in two parts.
7302 MockRead("lo"), MockRead(" world"),
7303 MockRead("junk"), // Should not be read!!
7304 MockRead(SYNCHRONOUS, OK),
7305 };
7306
7307 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7308 session_deps_.socket_factory->AddSocketDataProvider(&data);
7309
7310 TestCompletionCallback callback;
7311
7312 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7313 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7314
7315 EXPECT_THAT(callback.GetResult(rv), IsOk());
7316
7317 const HttpResponseInfo* response = trans.GetResponseInfo();
7318 ASSERT_TRUE(response);
7319 EXPECT_TRUE(response->headers);
7320 std::string status_line = response->headers->GetStatusLine();
7321 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7322
7323 // Make memory critical notification and ensure the transaction still has been
7324 // operating right.
7325 base::MemoryPressureListener::NotifyMemoryPressure(
7326 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7327 base::RunLoop().RunUntilIdle();
7328
7329 // Socket should not be flushed as long as it is not idle.
7330 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7331
7332 std::string response_data;
7333 rv = ReadTransaction(&trans, &response_data);
7334 EXPECT_THAT(rv, IsOk());
7335 EXPECT_EQ("hello world", response_data);
7336
7337 // Empty the current queue. This is necessary because idle sockets are
7338 // added to the connection pool asynchronously with a PostTask.
7339 base::RunLoop().RunUntilIdle();
7340
7341 // We now check to make sure the socket was added back to the pool.
7342 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7343
7344 // Idle sockets should NOT be flushed on moderate memory pressure.
7345 base::MemoryPressureListener::NotifyMemoryPressure(
7346 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7347 base::RunLoop().RunUntilIdle();
7348
7349 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7350
7351 // Idle sockets should NOT be flushed on critical memory pressure.
7352 base::MemoryPressureListener::NotifyMemoryPressure(
7353 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7354 base::RunLoop().RunUntilIdle();
7355
7356 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7357}
7358
maksim.sisov0adf8592016-07-15 06:25:567359// Grab an SSL socket, use it, and put it back into the pool. Then, make
7360// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017361TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567362 HttpRequestInfo request;
7363 request.method = "GET";
7364 request.url = GURL("https://www.example.org/");
7365 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107366 request.traffic_annotation =
7367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567368
7369 MockWrite data_writes[] = {
7370 MockWrite("GET / HTTP/1.1\r\n"
7371 "Host: www.example.org\r\n"
7372 "Connection: keep-alive\r\n\r\n"),
7373 };
7374
7375 MockRead data_reads[] = {
7376 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7377 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7378
7379 SSLSocketDataProvider ssl(ASYNC, OK);
7380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7381
7382 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7383 arraysize(data_writes));
7384 session_deps_.socket_factory->AddSocketDataProvider(&data);
7385
7386 TestCompletionCallback callback;
7387
7388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567390
7391 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207392 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567393
7394 EXPECT_THAT(callback.GetResult(rv), IsOk());
7395
bnc691fda62016-08-12 00:43:167396 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567397 ASSERT_TRUE(response);
7398 ASSERT_TRUE(response->headers);
7399 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7400
7401 // Make memory critical notification and ensure the transaction still has been
7402 // operating right.
7403 base::MemoryPressureListener::NotifyMemoryPressure(
7404 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7405 base::RunLoop().RunUntilIdle();
7406
7407 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7408
7409 std::string response_data;
bnc691fda62016-08-12 00:43:167410 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567411 EXPECT_THAT(rv, IsOk());
7412 EXPECT_EQ("hello world", response_data);
7413
7414 // Empty the current queue. This is necessary because idle sockets are
7415 // added to the connection pool asynchronously with a PostTask.
7416 base::RunLoop().RunUntilIdle();
7417
7418 // We now check to make sure the socket was added back to the pool.
7419 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7420
7421 // Make memory notification once again and ensure idle socket is closed.
7422 base::MemoryPressureListener::NotifyMemoryPressure(
7423 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7424 base::RunLoop().RunUntilIdle();
7425
7426 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7427}
7428
[email protected]b4404c02009-04-10 16:38:527429// Make sure that we recycle a socket after a zero-length response.
7430// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017431TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427432 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527433 request.method = "GET";
bncce36dca22015-04-21 22:11:237434 request.url = GURL(
7435 "http://www.example.org/csi?v=3&s=web&action=&"
7436 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7437 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7438 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:107439 request.traffic_annotation =
7440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527441
danakj1fd259a02016-04-16 03:17:097442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277443
[email protected]b4404c02009-04-10 16:38:527444 MockRead data_reads[] = {
7445 MockRead("HTTP/1.1 204 No Content\r\n"
7446 "Content-Length: 0\r\n"
7447 "Content-Type: text/html\r\n\r\n"),
7448 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067449 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527450 };
7451
[email protected]31a2bfe2010-02-09 08:03:397452 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077453 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527454
mmenkecc2298e2015-12-07 18:20:187455 // Transaction must be created after the MockReads, so it's destroyed before
7456 // them.
bnc691fda62016-08-12 00:43:167457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187458
[email protected]49639fa2011-12-20 23:22:417459 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527460
tfarina42834112016-09-22 13:38:207461 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527463
7464 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017465 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527466
bnc691fda62016-08-12 00:43:167467 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527468 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527469
wezca1070932016-05-26 20:30:527470 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527471 std::string status_line = response->headers->GetStatusLine();
7472 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7473
[email protected]90499482013-06-01 00:39:507474 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527475
7476 std::string response_data;
bnc691fda62016-08-12 00:43:167477 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017478 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527479 EXPECT_EQ("", response_data);
7480
7481 // Empty the current queue. This is necessary because idle sockets are
7482 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557483 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527484
7485 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507486 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527487}
7488
bncd16676a2016-07-20 16:23:017489TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097490 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227491 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197492 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227493 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277494
[email protected]1c773ea12009-04-28 19:58:427495 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517496 // Transaction 1: a GET request that succeeds. The socket is recycled
7497 // after use.
7498 request[0].method = "GET";
7499 request[0].url = GURL("http://www.google.com/");
7500 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107501 request[0].traffic_annotation =
7502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517503 // Transaction 2: a POST request. Reuses the socket kept alive from
7504 // transaction 1. The first attempts fails when writing the POST data.
7505 // This causes the transaction to retry with a new socket. The second
7506 // attempt succeeds.
7507 request[1].method = "POST";
7508 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277509 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517510 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107511 request[1].traffic_annotation =
7512 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517513
danakj1fd259a02016-04-16 03:17:097514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517515
7516 // The first socket is used for transaction 1 and the first attempt of
7517 // transaction 2.
7518
7519 // The response of transaction 1.
7520 MockRead data_reads1[] = {
7521 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7522 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067523 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517524 };
7525 // The mock write results of transaction 1 and the first attempt of
7526 // transaction 2.
7527 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067528 MockWrite(SYNCHRONOUS, 64), // GET
7529 MockWrite(SYNCHRONOUS, 93), // POST
7530 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517531 };
[email protected]31a2bfe2010-02-09 08:03:397532 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7533 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517534
7535 // The second socket is used for the second attempt of transaction 2.
7536
7537 // The response of transaction 2.
7538 MockRead data_reads2[] = {
7539 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7540 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067541 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517542 };
7543 // The mock write results of the second attempt of transaction 2.
7544 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067545 MockWrite(SYNCHRONOUS, 93), // POST
7546 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517547 };
[email protected]31a2bfe2010-02-09 08:03:397548 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7549 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517550
[email protected]bb88e1d32013-05-03 23:11:077551 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7552 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517553
thestig9d3bb0c2015-01-24 00:49:517554 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517555 "hello world", "welcome"
7556 };
7557
7558 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517560
[email protected]49639fa2011-12-20 23:22:417561 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517562
tfarina42834112016-09-22 13:38:207563 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517565
7566 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017567 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517568
bnc691fda62016-08-12 00:43:167569 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527570 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517571
wezca1070932016-05-26 20:30:527572 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517573 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7574
7575 std::string response_data;
bnc691fda62016-08-12 00:43:167576 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017577 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517578 EXPECT_EQ(kExpectedResponseData[i], response_data);
7579 }
7580}
[email protected]f9ee6b52008-11-08 06:46:237581
7582// Test the request-challenge-retry sequence for basic auth when there is
7583// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167584// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017585TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427586 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237587 request.method = "GET";
bncce36dca22015-04-21 22:11:237588 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417589 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107590 request.traffic_annotation =
7591 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297592
danakj1fd259a02016-04-16 03:17:097593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277595
[email protected]a97cca42009-08-14 01:00:297596 // The password contains an escaped character -- for this test to pass it
7597 // will need to be unescaped by HttpNetworkTransaction.
7598 EXPECT_EQ("b%40r", request.url.password());
7599
[email protected]f9ee6b52008-11-08 06:46:237600 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237601 MockWrite(
7602 "GET / HTTP/1.1\r\n"
7603 "Host: www.example.org\r\n"
7604 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237605 };
7606
7607 MockRead data_reads1[] = {
7608 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7609 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7610 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067611 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237612 };
7613
[email protected]2262e3a2012-05-22 16:08:167614 // After the challenge above, the transaction will be restarted using the
7615 // identity from the url (foo, b@r) to answer the challenge.
7616 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237617 MockWrite(
7618 "GET / HTTP/1.1\r\n"
7619 "Host: www.example.org\r\n"
7620 "Connection: keep-alive\r\n"
7621 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167622 };
7623
7624 MockRead data_reads2[] = {
7625 MockRead("HTTP/1.0 200 OK\r\n"),
7626 MockRead("Content-Length: 100\r\n\r\n"),
7627 MockRead(SYNCHRONOUS, OK),
7628 };
7629
[email protected]31a2bfe2010-02-09 08:03:397630 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7631 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167632 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7633 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077634 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7635 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237636
[email protected]49639fa2011-12-20 23:22:417637 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207638 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237640 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017641 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167642 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167643
7644 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167645 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167647 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017648 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167649 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227650
bnc691fda62016-08-12 00:43:167651 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527652 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167653
7654 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527655 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167656
7657 EXPECT_EQ(100, response->headers->GetContentLength());
7658
7659 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557660 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167661}
7662
7663// Test the request-challenge-retry sequence for basic auth when there is an
7664// incorrect identity in the URL. The identity from the URL should be used only
7665// once.
bncd16676a2016-07-20 16:23:017666TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167667 HttpRequestInfo request;
7668 request.method = "GET";
7669 // Note: the URL has a username:password in it. The password "baz" is
7670 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237671 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167672
7673 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107674 request.traffic_annotation =
7675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167676
danakj1fd259a02016-04-16 03:17:097677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167679
7680 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237681 MockWrite(
7682 "GET / HTTP/1.1\r\n"
7683 "Host: www.example.org\r\n"
7684 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167685 };
7686
7687 MockRead data_reads1[] = {
7688 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7689 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7690 MockRead("Content-Length: 10\r\n\r\n"),
7691 MockRead(SYNCHRONOUS, ERR_FAILED),
7692 };
7693
7694 // After the challenge above, the transaction will be restarted using the
7695 // identity from the url (foo, baz) to answer the challenge.
7696 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237697 MockWrite(
7698 "GET / HTTP/1.1\r\n"
7699 "Host: www.example.org\r\n"
7700 "Connection: keep-alive\r\n"
7701 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167702 };
7703
7704 MockRead data_reads2[] = {
7705 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7706 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7707 MockRead("Content-Length: 10\r\n\r\n"),
7708 MockRead(SYNCHRONOUS, ERR_FAILED),
7709 };
7710
7711 // After the challenge above, the transaction will be restarted using the
7712 // identity supplied by the user (foo, bar) to answer the challenge.
7713 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237714 MockWrite(
7715 "GET / HTTP/1.1\r\n"
7716 "Host: www.example.org\r\n"
7717 "Connection: keep-alive\r\n"
7718 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167719 };
7720
7721 MockRead data_reads3[] = {
7722 MockRead("HTTP/1.0 200 OK\r\n"),
7723 MockRead("Content-Length: 100\r\n\r\n"),
7724 MockRead(SYNCHRONOUS, OK),
7725 };
7726
7727 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7728 data_writes1, arraysize(data_writes1));
7729 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7730 data_writes2, arraysize(data_writes2));
7731 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7732 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077733 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7734 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7735 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167736
7737 TestCompletionCallback callback1;
7738
tfarina42834112016-09-22 13:38:207739 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167741
7742 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017743 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167744
bnc691fda62016-08-12 00:43:167745 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167746 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167747 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167749 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017750 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167751 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167752
bnc691fda62016-08-12 00:43:167753 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527754 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167755 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7756
7757 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167758 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167760 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017761 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167762 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167763
bnc691fda62016-08-12 00:43:167764 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527765 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167766
7767 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527768 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167769
7770 EXPECT_EQ(100, response->headers->GetContentLength());
7771
[email protected]ea9dc9a2009-09-05 00:43:327772 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557773 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327774}
7775
[email protected]2217aa22013-10-11 03:03:547776
7777// Test the request-challenge-retry sequence for basic auth when there is a
7778// correct identity in the URL, but its use is being suppressed. The identity
7779// from the URL should never be used.
bncd16676a2016-07-20 16:23:017780TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547781 HttpRequestInfo request;
7782 request.method = "GET";
bncce36dca22015-04-21 22:11:237783 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547784 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:107785 request.traffic_annotation =
7786 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547787
danakj1fd259a02016-04-16 03:17:097788 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167789 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547790
7791 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237792 MockWrite(
7793 "GET / HTTP/1.1\r\n"
7794 "Host: www.example.org\r\n"
7795 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547796 };
7797
7798 MockRead data_reads1[] = {
7799 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7800 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7801 MockRead("Content-Length: 10\r\n\r\n"),
7802 MockRead(SYNCHRONOUS, ERR_FAILED),
7803 };
7804
7805 // After the challenge above, the transaction will be restarted using the
7806 // identity supplied by the user, not the one in the URL, to answer the
7807 // challenge.
7808 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237809 MockWrite(
7810 "GET / HTTP/1.1\r\n"
7811 "Host: www.example.org\r\n"
7812 "Connection: keep-alive\r\n"
7813 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547814 };
7815
7816 MockRead data_reads3[] = {
7817 MockRead("HTTP/1.0 200 OK\r\n"),
7818 MockRead("Content-Length: 100\r\n\r\n"),
7819 MockRead(SYNCHRONOUS, OK),
7820 };
7821
7822 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7823 data_writes1, arraysize(data_writes1));
7824 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7825 data_writes3, arraysize(data_writes3));
7826 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7827 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7828
7829 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207830 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547832 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017833 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167834 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547835
bnc691fda62016-08-12 00:43:167836 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527837 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547838 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7839
7840 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167841 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547843 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017844 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167845 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547846
bnc691fda62016-08-12 00:43:167847 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527848 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547849
7850 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527851 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547852 EXPECT_EQ(100, response->headers->GetContentLength());
7853
7854 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557855 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547856}
7857
[email protected]f9ee6b52008-11-08 06:46:237858// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017859TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237861
7862 // Transaction 1: authenticate (foo, bar) on MyRealm1
7863 {
[email protected]1c773ea12009-04-28 19:58:427864 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237865 request.method = "GET";
bncce36dca22015-04-21 22:11:237866 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:107867 request.traffic_annotation =
7868 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237869
bnc691fda62016-08-12 00:43:167870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277871
[email protected]f9ee6b52008-11-08 06:46:237872 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237873 MockWrite(
7874 "GET /x/y/z HTTP/1.1\r\n"
7875 "Host: www.example.org\r\n"
7876 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237877 };
7878
7879 MockRead data_reads1[] = {
7880 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7881 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7882 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067883 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237884 };
7885
7886 // Resend with authorization (username=foo, password=bar)
7887 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237888 MockWrite(
7889 "GET /x/y/z HTTP/1.1\r\n"
7890 "Host: www.example.org\r\n"
7891 "Connection: keep-alive\r\n"
7892 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237893 };
7894
7895 // Sever accepts the authorization.
7896 MockRead data_reads2[] = {
7897 MockRead("HTTP/1.0 200 OK\r\n"),
7898 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067899 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237900 };
7901
[email protected]31a2bfe2010-02-09 08:03:397902 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7903 data_writes1, arraysize(data_writes1));
7904 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7905 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077906 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7907 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237908
[email protected]49639fa2011-12-20 23:22:417909 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237910
tfarina42834112016-09-22 13:38:207911 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237913
7914 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017915 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237916
bnc691fda62016-08-12 00:43:167917 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527918 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047919 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237920
[email protected]49639fa2011-12-20 23:22:417921 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237922
bnc691fda62016-08-12 00:43:167923 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7924 callback2.callback());
robpercival214763f2016-07-01 23:27:017925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237926
7927 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017928 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237929
bnc691fda62016-08-12 00:43:167930 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527931 ASSERT_TRUE(response);
7932 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237933 EXPECT_EQ(100, response->headers->GetContentLength());
7934 }
7935
7936 // ------------------------------------------------------------------------
7937
7938 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7939 {
[email protected]1c773ea12009-04-28 19:58:427940 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237941 request.method = "GET";
7942 // Note that Transaction 1 was at /x/y/z, so this is in the same
7943 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237944 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:107945 request.traffic_annotation =
7946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237947
bnc691fda62016-08-12 00:43:167948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277949
[email protected]f9ee6b52008-11-08 06:46:237950 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237951 MockWrite(
7952 "GET /x/y/a/b HTTP/1.1\r\n"
7953 "Host: www.example.org\r\n"
7954 "Connection: keep-alive\r\n"
7955 // Send preemptive authorization for MyRealm1
7956 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237957 };
7958
7959 // The server didn't like the preemptive authorization, and
7960 // challenges us for a different realm (MyRealm2).
7961 MockRead data_reads1[] = {
7962 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7963 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7964 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067965 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237966 };
7967
7968 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7969 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237970 MockWrite(
7971 "GET /x/y/a/b HTTP/1.1\r\n"
7972 "Host: www.example.org\r\n"
7973 "Connection: keep-alive\r\n"
7974 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237975 };
7976
7977 // Sever accepts the authorization.
7978 MockRead data_reads2[] = {
7979 MockRead("HTTP/1.0 200 OK\r\n"),
7980 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067981 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237982 };
7983
[email protected]31a2bfe2010-02-09 08:03:397984 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7985 data_writes1, arraysize(data_writes1));
7986 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7987 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7989 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237990
[email protected]49639fa2011-12-20 23:22:417991 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237992
tfarina42834112016-09-22 13:38:207993 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237995
7996 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017997 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237998
bnc691fda62016-08-12 00:43:167999 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528000 ASSERT_TRUE(response);
8001 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048002 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438003 EXPECT_EQ("http://www.example.org",
8004 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048005 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198006 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238007
[email protected]49639fa2011-12-20 23:22:418008 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238009
bnc691fda62016-08-12 00:43:168010 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8011 callback2.callback());
robpercival214763f2016-07-01 23:27:018012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238013
8014 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018015 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238016
bnc691fda62016-08-12 00:43:168017 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528018 ASSERT_TRUE(response);
8019 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238020 EXPECT_EQ(100, response->headers->GetContentLength());
8021 }
8022
8023 // ------------------------------------------------------------------------
8024
8025 // Transaction 3: Resend a request in MyRealm's protection space --
8026 // succeed with preemptive authorization.
8027 {
[email protected]1c773ea12009-04-28 19:58:428028 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238029 request.method = "GET";
bncce36dca22015-04-21 22:11:238030 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108031 request.traffic_annotation =
8032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238033
bnc691fda62016-08-12 00:43:168034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278035
[email protected]f9ee6b52008-11-08 06:46:238036 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238037 MockWrite(
8038 "GET /x/y/z2 HTTP/1.1\r\n"
8039 "Host: www.example.org\r\n"
8040 "Connection: keep-alive\r\n"
8041 // The authorization for MyRealm1 gets sent preemptively
8042 // (since the url is in the same protection space)
8043 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238044 };
8045
8046 // Sever accepts the preemptive authorization
8047 MockRead data_reads1[] = {
8048 MockRead("HTTP/1.0 200 OK\r\n"),
8049 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068050 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238051 };
8052
[email protected]31a2bfe2010-02-09 08:03:398053 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8054 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078055 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238056
[email protected]49639fa2011-12-20 23:22:418057 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238058
tfarina42834112016-09-22 13:38:208059 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238061
8062 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018063 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238064
bnc691fda62016-08-12 00:43:168065 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528066 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238067
wezca1070932016-05-26 20:30:528068 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238069 EXPECT_EQ(100, response->headers->GetContentLength());
8070 }
8071
8072 // ------------------------------------------------------------------------
8073
8074 // Transaction 4: request another URL in MyRealm (however the
8075 // url is not known to belong to the protection space, so no pre-auth).
8076 {
[email protected]1c773ea12009-04-28 19:58:428077 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238078 request.method = "GET";
bncce36dca22015-04-21 22:11:238079 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108080 request.traffic_annotation =
8081 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238082
bnc691fda62016-08-12 00:43:168083 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278084
[email protected]f9ee6b52008-11-08 06:46:238085 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238086 MockWrite(
8087 "GET /x/1 HTTP/1.1\r\n"
8088 "Host: www.example.org\r\n"
8089 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238090 };
8091
8092 MockRead data_reads1[] = {
8093 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8094 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8095 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068096 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238097 };
8098
8099 // Resend with authorization from MyRealm's cache.
8100 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238101 MockWrite(
8102 "GET /x/1 HTTP/1.1\r\n"
8103 "Host: www.example.org\r\n"
8104 "Connection: keep-alive\r\n"
8105 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238106 };
8107
8108 // Sever accepts the authorization.
8109 MockRead data_reads2[] = {
8110 MockRead("HTTP/1.0 200 OK\r\n"),
8111 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068112 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238113 };
8114
[email protected]31a2bfe2010-02-09 08:03:398115 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8116 data_writes1, arraysize(data_writes1));
8117 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8118 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078119 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8120 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238121
[email protected]49639fa2011-12-20 23:22:418122 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238123
tfarina42834112016-09-22 13:38:208124 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238126
8127 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018128 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238129
bnc691fda62016-08-12 00:43:168130 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418131 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168132 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018133 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228134 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018135 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168136 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228137
bnc691fda62016-08-12 00:43:168138 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528139 ASSERT_TRUE(response);
8140 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238141 EXPECT_EQ(100, response->headers->GetContentLength());
8142 }
8143
8144 // ------------------------------------------------------------------------
8145
8146 // Transaction 5: request a URL in MyRealm, but the server rejects the
8147 // cached identity. Should invalidate and re-prompt.
8148 {
[email protected]1c773ea12009-04-28 19:58:428149 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238150 request.method = "GET";
bncce36dca22015-04-21 22:11:238151 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:108152 request.traffic_annotation =
8153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238154
bnc691fda62016-08-12 00:43:168155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278156
[email protected]f9ee6b52008-11-08 06:46:238157 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238158 MockWrite(
8159 "GET /p/q/t HTTP/1.1\r\n"
8160 "Host: www.example.org\r\n"
8161 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238162 };
8163
8164 MockRead data_reads1[] = {
8165 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8166 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8167 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068168 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238169 };
8170
8171 // Resend with authorization from cache for MyRealm.
8172 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238173 MockWrite(
8174 "GET /p/q/t HTTP/1.1\r\n"
8175 "Host: www.example.org\r\n"
8176 "Connection: keep-alive\r\n"
8177 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238178 };
8179
8180 // Sever rejects the authorization.
8181 MockRead data_reads2[] = {
8182 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8183 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8184 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068185 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238186 };
8187
8188 // At this point we should prompt for new credentials for MyRealm.
8189 // Restart with username=foo3, password=foo4.
8190 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238191 MockWrite(
8192 "GET /p/q/t HTTP/1.1\r\n"
8193 "Host: www.example.org\r\n"
8194 "Connection: keep-alive\r\n"
8195 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238196 };
8197
8198 // Sever accepts the authorization.
8199 MockRead data_reads3[] = {
8200 MockRead("HTTP/1.0 200 OK\r\n"),
8201 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068202 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238203 };
8204
[email protected]31a2bfe2010-02-09 08:03:398205 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8206 data_writes1, arraysize(data_writes1));
8207 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8208 data_writes2, arraysize(data_writes2));
8209 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8210 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078211 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8212 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8213 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238214
[email protected]49639fa2011-12-20 23:22:418215 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238216
tfarina42834112016-09-22 13:38:208217 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238219
8220 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018221 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238222
bnc691fda62016-08-12 00:43:168223 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418224 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168225 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228227 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018228 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168229 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228230
bnc691fda62016-08-12 00:43:168231 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528232 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048233 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238234
[email protected]49639fa2011-12-20 23:22:418235 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238236
bnc691fda62016-08-12 00:43:168237 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8238 callback3.callback());
robpercival214763f2016-07-01 23:27:018239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238240
[email protected]0757e7702009-03-27 04:00:228241 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018242 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238243
bnc691fda62016-08-12 00:43:168244 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528245 ASSERT_TRUE(response);
8246 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238247 EXPECT_EQ(100, response->headers->GetContentLength());
8248 }
8249}
[email protected]89ceba9a2009-03-21 03:46:068250
[email protected]3c32c5f2010-05-18 15:18:128251// Tests that nonce count increments when multiple auth attempts
8252// are started with the same nonce.
bncd16676a2016-07-20 16:23:018253TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448254 HttpAuthHandlerDigest::Factory* digest_factory =
8255 new HttpAuthHandlerDigest::Factory();
8256 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8257 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8258 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078259 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128261
8262 // Transaction 1: authenticate (foo, bar) on MyRealm1
8263 {
[email protected]3c32c5f2010-05-18 15:18:128264 HttpRequestInfo request;
8265 request.method = "GET";
bncce36dca22015-04-21 22:11:238266 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108267 request.traffic_annotation =
8268 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128269
bnc691fda62016-08-12 00:43:168270 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278271
[email protected]3c32c5f2010-05-18 15:18:128272 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238273 MockWrite(
8274 "GET /x/y/z HTTP/1.1\r\n"
8275 "Host: www.example.org\r\n"
8276 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128277 };
8278
8279 MockRead data_reads1[] = {
8280 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8281 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8282 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068283 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128284 };
8285
8286 // Resend with authorization (username=foo, password=bar)
8287 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238288 MockWrite(
8289 "GET /x/y/z HTTP/1.1\r\n"
8290 "Host: www.example.org\r\n"
8291 "Connection: keep-alive\r\n"
8292 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8293 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8294 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8295 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128296 };
8297
8298 // Sever accepts the authorization.
8299 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088300 MockRead("HTTP/1.0 200 OK\r\n"),
8301 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128302 };
8303
8304 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8305 data_writes1, arraysize(data_writes1));
8306 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8307 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078308 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8309 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128310
[email protected]49639fa2011-12-20 23:22:418311 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128312
tfarina42834112016-09-22 13:38:208313 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018314 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128315
8316 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018317 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128318
bnc691fda62016-08-12 00:43:168319 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528320 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048321 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128322
[email protected]49639fa2011-12-20 23:22:418323 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128324
bnc691fda62016-08-12 00:43:168325 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8326 callback2.callback());
robpercival214763f2016-07-01 23:27:018327 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128328
8329 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018330 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128331
bnc691fda62016-08-12 00:43:168332 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528333 ASSERT_TRUE(response);
8334 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128335 }
8336
8337 // ------------------------------------------------------------------------
8338
8339 // Transaction 2: Request another resource in digestive's protection space.
8340 // This will preemptively add an Authorization header which should have an
8341 // "nc" value of 2 (as compared to 1 in the first use.
8342 {
[email protected]3c32c5f2010-05-18 15:18:128343 HttpRequestInfo request;
8344 request.method = "GET";
8345 // Note that Transaction 1 was at /x/y/z, so this is in the same
8346 // protection space as digest.
bncce36dca22015-04-21 22:11:238347 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108348 request.traffic_annotation =
8349 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128350
bnc691fda62016-08-12 00:43:168351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278352
[email protected]3c32c5f2010-05-18 15:18:128353 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238354 MockWrite(
8355 "GET /x/y/a/b HTTP/1.1\r\n"
8356 "Host: www.example.org\r\n"
8357 "Connection: keep-alive\r\n"
8358 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8359 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8360 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8361 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128362 };
8363
8364 // Sever accepts the authorization.
8365 MockRead data_reads1[] = {
8366 MockRead("HTTP/1.0 200 OK\r\n"),
8367 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068368 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128369 };
8370
8371 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8372 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078373 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128374
[email protected]49639fa2011-12-20 23:22:418375 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128376
tfarina42834112016-09-22 13:38:208377 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128379
8380 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018381 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128382
bnc691fda62016-08-12 00:43:168383 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528384 ASSERT_TRUE(response);
8385 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128386 }
8387}
8388
[email protected]89ceba9a2009-03-21 03:46:068389// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018390TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068391 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068394
8395 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168396 trans.read_buf_ = new IOBuffer(15);
8397 trans.read_buf_len_ = 15;
8398 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068399
8400 // Setup state in response_
bnc691fda62016-08-12 00:43:168401 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578402 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088403 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578404 response->response_time = base::Time::Now();
8405 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068406
8407 { // Setup state for response_.vary_data
8408 HttpRequestInfo request;
8409 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8410 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278411 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438412 request.extra_headers.SetHeader("Foo", "1");
8413 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508414 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068415 }
8416
8417 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168418 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068419
8420 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168421 EXPECT_FALSE(trans.read_buf_);
8422 EXPECT_EQ(0, trans.read_buf_len_);
8423 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528424 EXPECT_FALSE(response->auth_challenge);
8425 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048426 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088427 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578428 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068429}
8430
[email protected]bacff652009-03-31 17:50:338431// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018432TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338433 HttpRequestInfo request;
8434 request.method = "GET";
bncce36dca22015-04-21 22:11:238435 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108436 request.traffic_annotation =
8437 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338438
danakj1fd259a02016-04-16 03:17:098439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278441
[email protected]bacff652009-03-31 17:50:338442 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238443 MockWrite(
8444 "GET / HTTP/1.1\r\n"
8445 "Host: www.example.org\r\n"
8446 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338447 };
8448
8449 MockRead data_reads[] = {
8450 MockRead("HTTP/1.0 200 OK\r\n"),
8451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8452 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068453 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338454 };
8455
[email protected]5ecc992a42009-11-11 01:41:598456 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398457 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8458 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068459 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8460 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338461
[email protected]bb88e1d32013-05-03 23:11:078462 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8463 session_deps_.socket_factory->AddSocketDataProvider(&data);
8464 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338466
[email protected]49639fa2011-12-20 23:22:418467 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338468
tfarina42834112016-09-22 13:38:208469 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338471
8472 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018473 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338474
bnc691fda62016-08-12 00:43:168475 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338477
8478 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018479 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338480
bnc691fda62016-08-12 00:43:168481 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338482
wezca1070932016-05-26 20:30:528483 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338484 EXPECT_EQ(100, response->headers->GetContentLength());
8485}
8486
8487// Test HTTPS connections to a site with a bad certificate, going through a
8488// proxy
bncd16676a2016-07-20 16:23:018489TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598490 session_deps_.proxy_resolution_service =
8491 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:338492
8493 HttpRequestInfo request;
8494 request.method = "GET";
bncce36dca22015-04-21 22:11:238495 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108496 request.traffic_annotation =
8497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338498
8499 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178500 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8501 "Host: www.example.org:443\r\n"
8502 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338503 };
8504
8505 MockRead proxy_reads[] = {
8506 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068507 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338508 };
8509
8510 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178511 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8512 "Host: www.example.org:443\r\n"
8513 "Proxy-Connection: keep-alive\r\n\r\n"),
8514 MockWrite("GET / HTTP/1.1\r\n"
8515 "Host: www.example.org\r\n"
8516 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338517 };
8518
8519 MockRead data_reads[] = {
8520 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8521 MockRead("HTTP/1.0 200 OK\r\n"),
8522 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8523 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068524 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338525 };
8526
[email protected]31a2bfe2010-02-09 08:03:398527 StaticSocketDataProvider ssl_bad_certificate(
8528 proxy_reads, arraysize(proxy_reads),
8529 proxy_writes, arraysize(proxy_writes));
8530 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8531 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068532 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8533 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338534
[email protected]bb88e1d32013-05-03 23:11:078535 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8536 session_deps_.socket_factory->AddSocketDataProvider(&data);
8537 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338539
[email protected]49639fa2011-12-20 23:22:418540 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338541
8542 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078543 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338544
danakj1fd259a02016-04-16 03:17:098545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338547
tfarina42834112016-09-22 13:38:208548 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338550
8551 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018552 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338553
bnc691fda62016-08-12 00:43:168554 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338556
8557 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018558 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338559
bnc691fda62016-08-12 00:43:168560 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338561
wezca1070932016-05-26 20:30:528562 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338563 EXPECT_EQ(100, response->headers->GetContentLength());
8564 }
8565}
8566
[email protected]2df19bb2010-08-25 20:13:468567
8568// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018569TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598570 session_deps_.proxy_resolution_service =
8571 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518572 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078573 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468574
8575 HttpRequestInfo request;
8576 request.method = "GET";
bncce36dca22015-04-21 22:11:238577 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108578 request.traffic_annotation =
8579 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468580
8581 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178582 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8583 "Host: www.example.org:443\r\n"
8584 "Proxy-Connection: keep-alive\r\n\r\n"),
8585 MockWrite("GET / HTTP/1.1\r\n"
8586 "Host: www.example.org\r\n"
8587 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468588 };
8589
8590 MockRead data_reads[] = {
8591 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8592 MockRead("HTTP/1.1 200 OK\r\n"),
8593 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8594 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068595 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468596 };
8597
8598 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8599 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068600 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8601 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468602
[email protected]bb88e1d32013-05-03 23:11:078603 session_deps_.socket_factory->AddSocketDataProvider(&data);
8604 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8605 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468606
[email protected]49639fa2011-12-20 23:22:418607 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468608
danakj1fd259a02016-04-16 03:17:098609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468611
tfarina42834112016-09-22 13:38:208612 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468614
8615 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018616 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168617 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468618
wezca1070932016-05-26 20:30:528619 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468620
tbansal2ecbbc72016-10-06 17:15:478621 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468622 EXPECT_TRUE(response->headers->IsKeepAlive());
8623 EXPECT_EQ(200, response->headers->response_code());
8624 EXPECT_EQ(100, response->headers->GetContentLength());
8625 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208626
8627 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168628 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208629 TestLoadTimingNotReusedWithPac(load_timing_info,
8630 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468631}
8632
[email protected]511f6f52010-12-17 03:58:298633// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018634TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598635 session_deps_.proxy_resolution_service =
8636 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518637 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078638 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298639
8640 HttpRequestInfo request;
8641 request.method = "GET";
bncce36dca22015-04-21 22:11:238642 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108643 request.traffic_annotation =
8644 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298645
8646 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178647 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8648 "Host: www.example.org:443\r\n"
8649 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298650 };
8651
8652 MockRead data_reads[] = {
8653 MockRead("HTTP/1.1 302 Redirect\r\n"),
8654 MockRead("Location: http://login.example.com/\r\n"),
8655 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068656 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298657 };
8658
8659 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8660 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068661 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298662
[email protected]bb88e1d32013-05-03 23:11:078663 session_deps_.socket_factory->AddSocketDataProvider(&data);
8664 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298665
[email protected]49639fa2011-12-20 23:22:418666 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298667
danakj1fd259a02016-04-16 03:17:098668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298670
tfarina42834112016-09-22 13:38:208671 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298673
8674 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018675 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168676 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298677
wezca1070932016-05-26 20:30:528678 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298679
8680 EXPECT_EQ(302, response->headers->response_code());
8681 std::string url;
8682 EXPECT_TRUE(response->headers->IsRedirect(&url));
8683 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208684
8685 // In the case of redirects from proxies, HttpNetworkTransaction returns
8686 // timing for the proxy connection instead of the connection to the host,
8687 // and no send / receive times.
8688 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8689 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168690 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208691
8692 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198693 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208694
8695 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8696 EXPECT_LE(load_timing_info.proxy_resolve_start,
8697 load_timing_info.proxy_resolve_end);
8698 EXPECT_LE(load_timing_info.proxy_resolve_end,
8699 load_timing_info.connect_timing.connect_start);
8700 ExpectConnectTimingHasTimes(
8701 load_timing_info.connect_timing,
8702 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8703
8704 EXPECT_TRUE(load_timing_info.send_start.is_null());
8705 EXPECT_TRUE(load_timing_info.send_end.is_null());
8706 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298707}
8708
8709// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018710TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598711 session_deps_.proxy_resolution_service =
8712 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298713
8714 HttpRequestInfo request;
8715 request.method = "GET";
bncce36dca22015-04-21 22:11:238716 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108717 request.traffic_annotation =
8718 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298719
bncdf80d44fd2016-07-15 20:27:418720 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238721 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418722 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088723 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298724 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418725 CreateMockWrite(conn, 0, SYNCHRONOUS),
8726 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298727 };
8728
8729 static const char* const kExtraHeaders[] = {
8730 "location",
8731 "http://login.example.com/",
8732 };
bnc42331402016-07-25 13:36:158733 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238734 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298735 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418736 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298737 };
8738
rch8e6c6c42015-05-01 14:05:138739 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8740 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068741 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368742 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298743
[email protected]bb88e1d32013-05-03 23:11:078744 session_deps_.socket_factory->AddSocketDataProvider(&data);
8745 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298746
[email protected]49639fa2011-12-20 23:22:418747 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298748
danakj1fd259a02016-04-16 03:17:098749 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168750 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298751
tfarina42834112016-09-22 13:38:208752 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298754
8755 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018756 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168757 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298758
wezca1070932016-05-26 20:30:528759 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298760
8761 EXPECT_EQ(302, response->headers->response_code());
8762 std::string url;
8763 EXPECT_TRUE(response->headers->IsRedirect(&url));
8764 EXPECT_EQ("http://login.example.com/", url);
8765}
8766
[email protected]4eddbc732012-08-09 05:40:178767// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018768TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598769 session_deps_.proxy_resolution_service =
8770 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298771
8772 HttpRequestInfo request;
8773 request.method = "GET";
bncce36dca22015-04-21 22:11:238774 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108775 request.traffic_annotation =
8776 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298777
8778 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178779 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8780 "Host: www.example.org:443\r\n"
8781 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298782 };
8783
8784 MockRead data_reads[] = {
8785 MockRead("HTTP/1.1 404 Not Found\r\n"),
8786 MockRead("Content-Length: 23\r\n\r\n"),
8787 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068788 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298789 };
8790
8791 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8792 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068793 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298794
[email protected]bb88e1d32013-05-03 23:11:078795 session_deps_.socket_factory->AddSocketDataProvider(&data);
8796 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298797
[email protected]49639fa2011-12-20 23:22:418798 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298799
danakj1fd259a02016-04-16 03:17:098800 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298802
tfarina42834112016-09-22 13:38:208803 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298805
8806 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018807 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298808
ttuttle960fcbf2016-04-19 13:26:328809 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298810}
8811
[email protected]4eddbc732012-08-09 05:40:178812// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018813TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598814 session_deps_.proxy_resolution_service =
8815 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298816
8817 HttpRequestInfo request;
8818 request.method = "GET";
bncce36dca22015-04-21 22:11:238819 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108820 request.traffic_annotation =
8821 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298822
bncdf80d44fd2016-07-15 20:27:418823 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238824 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418825 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088826 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298827 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418828 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298829 };
8830
8831 static const char* const kExtraHeaders[] = {
8832 "location",
8833 "http://login.example.com/",
8834 };
bnc42331402016-07-25 13:36:158835 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238836 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Bence Békyd74f4382018-02-20 18:26:198837 SpdySerializedFrame body(
8838 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298839 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418840 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138841 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298842 };
8843
rch8e6c6c42015-05-01 14:05:138844 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8845 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068846 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368847 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298848
[email protected]bb88e1d32013-05-03 23:11:078849 session_deps_.socket_factory->AddSocketDataProvider(&data);
8850 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298851
[email protected]49639fa2011-12-20 23:22:418852 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298853
danakj1fd259a02016-04-16 03:17:098854 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168855 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298856
tfarina42834112016-09-22 13:38:208857 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298859
8860 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018861 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298862
ttuttle960fcbf2016-04-19 13:26:328863 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298864}
8865
[email protected]0c5fb722012-02-28 11:50:358866// Test the request-challenge-retry sequence for basic auth, through
8867// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018868TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358869 HttpRequestInfo request;
8870 request.method = "GET";
bncce36dca22015-04-21 22:11:238871 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358872 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298873 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:108874 request.traffic_annotation =
8875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358876
8877 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598878 session_deps_.proxy_resolution_service =
8879 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518880 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078881 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358883
8884 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418885 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238886 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418887 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088888 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388889 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358890
bnc691fda62016-08-12 00:43:168891 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358892 // be issuing -- the final header line contains the credentials.
8893 const char* const kAuthCredentials[] = {
8894 "proxy-authorization", "Basic Zm9vOmJhcg==",
8895 };
bncdf80d44fd2016-07-15 20:27:418896 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348897 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238898 HostPortPair("www.example.org", 443)));
8899 // fetch https://www.example.org/ via HTTP
8900 const char get[] =
8901 "GET / HTTP/1.1\r\n"
8902 "Host: www.example.org\r\n"
8903 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418904 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198905 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358906
8907 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418908 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8909 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358910 };
8911
8912 // The proxy responds to the connect with a 407, using a persistent
8913 // connection.
thestig9d3bb0c2015-01-24 00:49:518914 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358915 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358916 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8917 };
bnc42331402016-07-25 13:36:158918 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418919 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358920
bnc42331402016-07-25 13:36:158921 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358922 const char resp[] = "HTTP/1.1 200 OK\r\n"
8923 "Content-Length: 5\r\n\r\n";
8924
bncdf80d44fd2016-07-15 20:27:418925 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198926 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
bncdf80d44fd2016-07-15 20:27:418927 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198928 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358929 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418930 CreateMockRead(conn_auth_resp, 1, ASYNC),
8931 CreateMockRead(conn_resp, 4, ASYNC),
8932 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8933 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138934 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358935 };
8936
rch8e6c6c42015-05-01 14:05:138937 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8938 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078939 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358940 // Negotiate SPDY to the proxy
8941 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368942 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078943 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358944 // Vanilla SSL to the server
8945 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078946 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358947
8948 TestCompletionCallback callback1;
8949
bnc87dcefc2017-05-25 12:47:588950 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198951 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358952
8953 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358955
8956 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018957 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468958 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358959 log.GetEntries(&entries);
8960 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008961 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8962 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358963 ExpectLogContainsSomewhere(
8964 entries, pos,
mikecirone8b85c432016-09-08 19:11:008965 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8966 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358967
8968 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528969 ASSERT_TRUE(response);
8970 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358971 EXPECT_EQ(407, response->headers->response_code());
8972 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528973 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438974 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358975
8976 TestCompletionCallback callback2;
8977
8978 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8979 callback2.callback());
robpercival214763f2016-07-01 23:27:018980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358981
8982 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018983 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358984
8985 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528986 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358987
8988 EXPECT_TRUE(response->headers->IsKeepAlive());
8989 EXPECT_EQ(200, response->headers->response_code());
8990 EXPECT_EQ(5, response->headers->GetContentLength());
8991 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8992
8993 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528994 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358995
[email protected]029c83b62013-01-24 05:28:208996 LoadTimingInfo load_timing_info;
8997 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8998 TestLoadTimingNotReusedWithPac(load_timing_info,
8999 CONNECT_TIMING_HAS_SSL_TIMES);
9000
[email protected]0c5fb722012-02-28 11:50:359001 trans.reset();
9002 session->CloseAllConnections();
9003}
9004
[email protected]7c6f7ba2012-04-03 04:09:299005// Test that an explicitly trusted SPDY proxy can push a resource from an
9006// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019007TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159008 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199009 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159010 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9011 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299012 HttpRequestInfo request;
9013 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109014 request.traffic_annotation =
9015 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299016
[email protected]7c6f7ba2012-04-03 04:09:299017 request.method = "GET";
bncce36dca22015-04-21 22:11:239018 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299019 push_request.method = "GET";
9020 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109021 push_request.traffic_annotation =
9022 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299023
tbansal28e68f82016-02-04 02:56:159024 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599025 session_deps_.proxy_resolution_service =
9026 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:519027 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079028 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509029
inlinechan894515af2016-12-09 02:40:109030 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509031
danakj1fd259a02016-04-16 03:17:099032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299033
bncdf80d44fd2016-07-15 20:27:419034 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459035 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359036 SpdySerializedFrame stream2_priority(
9037 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299038
9039 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419040 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359041 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299042 };
9043
Bence Béky7bf94362018-01-10 13:19:369044 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9045 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9046
bncdf80d44fd2016-07-15 20:27:419047 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159048 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299049
bncdf80d44fd2016-07-15 20:27:419050 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299051
Bence Békyd74f4382018-02-20 18:26:199052 SpdySerializedFrame stream2_body(
9053 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299054
9055 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369056 CreateMockRead(stream2_syn, 1, ASYNC),
9057 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359058 CreateMockRead(stream1_body, 4, ASYNC),
9059 CreateMockRead(stream2_body, 5, ASYNC),
9060 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299061 };
9062
rch8e6c6c42015-05-01 14:05:139063 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9064 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079065 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299066 // Negotiate SPDY to the proxy
9067 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369068 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079069 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299070
bnc87dcefc2017-05-25 12:47:589071 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199072 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299073 TestCompletionCallback callback;
9074 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019075 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299076
9077 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019078 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299079 const HttpResponseInfo* response = trans->GetResponseInfo();
9080
bnc87dcefc2017-05-25 12:47:589081 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199082 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509083 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299085
9086 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019087 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299088 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9089
wezca1070932016-05-26 20:30:529090 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299091 EXPECT_TRUE(response->headers->IsKeepAlive());
9092
9093 EXPECT_EQ(200, response->headers->response_code());
9094 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9095
9096 std::string response_data;
9097 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019098 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299099 EXPECT_EQ("hello!", response_data);
9100
[email protected]029c83b62013-01-24 05:28:209101 LoadTimingInfo load_timing_info;
9102 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9103 TestLoadTimingNotReusedWithPac(load_timing_info,
9104 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9105
[email protected]7c6f7ba2012-04-03 04:09:299106 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529107 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299108 EXPECT_EQ(200, push_response->headers->response_code());
9109
9110 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019111 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299112 EXPECT_EQ("pushed", response_data);
9113
[email protected]029c83b62013-01-24 05:28:209114 LoadTimingInfo push_load_timing_info;
9115 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9116 TestLoadTimingReusedWithPac(push_load_timing_info);
9117 // The transactions should share a socket ID, despite being for different
9118 // origins.
9119 EXPECT_EQ(load_timing_info.socket_log_id,
9120 push_load_timing_info.socket_log_id);
9121
[email protected]7c6f7ba2012-04-03 04:09:299122 trans.reset();
9123 push_trans.reset();
9124 session->CloseAllConnections();
9125}
9126
[email protected]8c843192012-04-05 07:15:009127// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019128TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159129 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199130 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159131 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9132 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009133 HttpRequestInfo request;
9134
9135 request.method = "GET";
bncce36dca22015-04-21 22:11:239136 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109137 request.traffic_annotation =
9138 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009139
Lily Houghton8c2f97d2018-01-22 05:06:599140 session_deps_.proxy_resolution_service =
9141 ProxyResolutionService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:519142 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079143 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509144
9145 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109146 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509147
danakj1fd259a02016-04-16 03:17:099148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009149
bncdf80d44fd2016-07-15 20:27:419150 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459151 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009152
bncdf80d44fd2016-07-15 20:27:419153 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089154 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009155
9156 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419157 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009158 };
9159
bncdf80d44fd2016-07-15 20:27:419160 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159161 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009162
bncdf80d44fd2016-07-15 20:27:419163 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009164
bncdf80d44fd2016-07-15 20:27:419165 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559166 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009167
9168 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419169 CreateMockRead(stream1_reply, 1, ASYNC),
9170 CreateMockRead(stream2_syn, 2, ASYNC),
9171 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599172 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009173 };
9174
rch8e6c6c42015-05-01 14:05:139175 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9176 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079177 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009178 // Negotiate SPDY to the proxy
9179 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369180 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079181 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009182
bnc87dcefc2017-05-25 12:47:589183 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199184 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009185 TestCompletionCallback callback;
9186 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009188
9189 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019190 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009191 const HttpResponseInfo* response = trans->GetResponseInfo();
9192
wezca1070932016-05-26 20:30:529193 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009194 EXPECT_TRUE(response->headers->IsKeepAlive());
9195
9196 EXPECT_EQ(200, response->headers->response_code());
9197 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9198
9199 std::string response_data;
9200 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019201 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009202 EXPECT_EQ("hello!", response_data);
9203
9204 trans.reset();
9205 session->CloseAllConnections();
9206}
9207
tbansal8ef1d3e2016-02-03 04:05:429208// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9209// resources.
bncd16676a2016-07-20 16:23:019210TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159211 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199212 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159213 proxy_delegate->set_trusted_spdy_proxy(
9214 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9215
tbansal8ef1d3e2016-02-03 04:05:429216 HttpRequestInfo request;
9217
9218 request.method = "GET";
9219 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109220 request.traffic_annotation =
9221 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429222
9223 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599224 session_deps_.proxy_resolution_service =
9225 ProxyResolutionService::CreateFixed("https://myproxy:70");
tbansal8ef1d3e2016-02-03 04:05:429226 BoundTestNetLog log;
9227 session_deps_.net_log = log.bound().net_log();
9228
9229 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109230 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429231
danakj1fd259a02016-04-16 03:17:099232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429233
bncdf80d44fd2016-07-15 20:27:419234 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459235 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359236 SpdySerializedFrame stream2_priority(
9237 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429238
9239 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419240 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359241 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429242 };
9243
bncdf80d44fd2016-07-15 20:27:419244 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159245 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429246
bncdf80d44fd2016-07-15 20:27:419247 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339248 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499249
bncdf80d44fd2016-07-15 20:27:419250 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429251
bncdf80d44fd2016-07-15 20:27:419252 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159253 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429254
bncdf80d44fd2016-07-15 20:27:419255 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429256
9257 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419258 CreateMockRead(stream1_reply, 1, ASYNC),
9259 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359260 CreateMockRead(stream1_body, 4, ASYNC),
9261 CreateMockRead(stream2_body, 5, ASYNC),
9262 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429263 };
9264
9265 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9266 arraysize(spdy_writes));
9267 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9268 // Negotiate SPDY to the proxy
9269 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369270 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429271 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9272
bnc87dcefc2017-05-25 12:47:589273 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199274 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429275 TestCompletionCallback callback;
9276 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429278
9279 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019280 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429281 const HttpResponseInfo* response = trans->GetResponseInfo();
9282
wezca1070932016-05-26 20:30:529283 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429284 EXPECT_TRUE(response->headers->IsKeepAlive());
9285
9286 EXPECT_EQ(200, response->headers->response_code());
9287 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9288
9289 std::string response_data;
9290 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019291 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429292 EXPECT_EQ("hello!", response_data);
9293
9294 trans.reset();
9295 session->CloseAllConnections();
9296}
9297
[email protected]2df19bb2010-08-25 20:13:469298// Test HTTPS connections to a site with a bad certificate, going through an
9299// HTTPS proxy
bncd16676a2016-07-20 16:23:019300TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599301 session_deps_.proxy_resolution_service =
9302 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:469303
9304 HttpRequestInfo request;
9305 request.method = "GET";
bncce36dca22015-04-21 22:11:239306 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109307 request.traffic_annotation =
9308 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469309
9310 // Attempt to fetch the URL from a server with a bad cert
9311 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179312 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9313 "Host: www.example.org:443\r\n"
9314 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469315 };
9316
9317 MockRead bad_cert_reads[] = {
9318 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069319 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469320 };
9321
9322 // Attempt to fetch the URL with a good cert
9323 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179324 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9325 "Host: www.example.org:443\r\n"
9326 "Proxy-Connection: keep-alive\r\n\r\n"),
9327 MockWrite("GET / HTTP/1.1\r\n"
9328 "Host: www.example.org\r\n"
9329 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469330 };
9331
9332 MockRead good_cert_reads[] = {
9333 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9334 MockRead("HTTP/1.0 200 OK\r\n"),
9335 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9336 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069337 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469338 };
9339
9340 StaticSocketDataProvider ssl_bad_certificate(
9341 bad_cert_reads, arraysize(bad_cert_reads),
9342 bad_cert_writes, arraysize(bad_cert_writes));
9343 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9344 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069345 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9346 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469347
9348 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079349 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9350 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469352
9353 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9355 session_deps_.socket_factory->AddSocketDataProvider(&data);
9356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469357
[email protected]49639fa2011-12-20 23:22:419358 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469359
danakj1fd259a02016-04-16 03:17:099360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469362
tfarina42834112016-09-22 13:38:209363 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469365
9366 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019367 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469368
bnc691fda62016-08-12 00:43:169369 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469371
9372 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019373 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469374
bnc691fda62016-08-12 00:43:169375 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469376
wezca1070932016-05-26 20:30:529377 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469378 EXPECT_EQ(100, response->headers->GetContentLength());
9379}
9380
bncd16676a2016-07-20 16:23:019381TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429382 HttpRequestInfo request;
9383 request.method = "GET";
bncce36dca22015-04-21 22:11:239384 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439385 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9386 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109387 request.traffic_annotation =
9388 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429389
danakj1fd259a02016-04-16 03:17:099390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169391 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279392
[email protected]1c773ea12009-04-28 19:58:429393 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239394 MockWrite(
9395 "GET / HTTP/1.1\r\n"
9396 "Host: www.example.org\r\n"
9397 "Connection: keep-alive\r\n"
9398 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429399 };
9400
9401 // Lastly, the server responds with the actual content.
9402 MockRead data_reads[] = {
9403 MockRead("HTTP/1.0 200 OK\r\n"),
9404 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9405 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069406 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429407 };
9408
[email protected]31a2bfe2010-02-09 08:03:399409 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9410 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079411 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429412
[email protected]49639fa2011-12-20 23:22:419413 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429414
tfarina42834112016-09-22 13:38:209415 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019416 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429417
9418 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019419 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429420}
9421
bncd16676a2016-07-20 16:23:019422TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299423 HttpRequestInfo request;
9424 request.method = "GET";
bncce36dca22015-04-21 22:11:239425 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299426 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9427 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109428 request.traffic_annotation =
9429 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299430
Lily Houghton8c2f97d2018-01-22 05:06:599431 session_deps_.proxy_resolution_service =
9432 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:099433 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169434 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279435
[email protected]da81f132010-08-18 23:39:299436 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179437 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9438 "Host: www.example.org:443\r\n"
9439 "Proxy-Connection: keep-alive\r\n"
9440 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299441 };
9442 MockRead data_reads[] = {
9443 // Return an error, so the transaction stops here (this test isn't
9444 // interested in the rest).
9445 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9446 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9447 MockRead("Proxy-Connection: close\r\n\r\n"),
9448 };
9449
9450 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9451 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079452 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299453
[email protected]49639fa2011-12-20 23:22:419454 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299455
tfarina42834112016-09-22 13:38:209456 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299458
9459 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019460 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299461}
9462
bncd16676a2016-07-20 16:23:019463TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429464 HttpRequestInfo request;
9465 request.method = "GET";
bncce36dca22015-04-21 22:11:239466 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169467 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9468 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:109469 request.traffic_annotation =
9470 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429471
danakj1fd259a02016-04-16 03:17:099472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279474
[email protected]1c773ea12009-04-28 19:58:429475 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239476 MockWrite(
9477 "GET / HTTP/1.1\r\n"
9478 "Host: www.example.org\r\n"
9479 "Connection: keep-alive\r\n"
9480 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429481 };
9482
9483 // Lastly, the server responds with the actual content.
9484 MockRead data_reads[] = {
9485 MockRead("HTTP/1.0 200 OK\r\n"),
9486 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9487 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069488 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429489 };
9490
[email protected]31a2bfe2010-02-09 08:03:399491 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9492 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079493 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429494
[email protected]49639fa2011-12-20 23:22:419495 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429496
tfarina42834112016-09-22 13:38:209497 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429499
9500 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019501 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429502}
9503
bncd16676a2016-07-20 16:23:019504TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429505 HttpRequestInfo request;
9506 request.method = "POST";
bncce36dca22015-04-21 22:11:239507 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109508 request.traffic_annotation =
9509 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429510
danakj1fd259a02016-04-16 03:17:099511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279513
[email protected]1c773ea12009-04-28 19:58:429514 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239515 MockWrite(
9516 "POST / HTTP/1.1\r\n"
9517 "Host: www.example.org\r\n"
9518 "Connection: keep-alive\r\n"
9519 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429520 };
9521
9522 // Lastly, the server responds with the actual content.
9523 MockRead data_reads[] = {
9524 MockRead("HTTP/1.0 200 OK\r\n"),
9525 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9526 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069527 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429528 };
9529
[email protected]31a2bfe2010-02-09 08:03:399530 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9531 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079532 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429533
[email protected]49639fa2011-12-20 23:22:419534 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429535
tfarina42834112016-09-22 13:38:209536 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429538
9539 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019540 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429541}
9542
bncd16676a2016-07-20 16:23:019543TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429544 HttpRequestInfo request;
9545 request.method = "PUT";
bncce36dca22015-04-21 22:11:239546 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109547 request.traffic_annotation =
9548 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429549
danakj1fd259a02016-04-16 03:17:099550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279552
[email protected]1c773ea12009-04-28 19:58:429553 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239554 MockWrite(
9555 "PUT / HTTP/1.1\r\n"
9556 "Host: www.example.org\r\n"
9557 "Connection: keep-alive\r\n"
9558 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429559 };
9560
9561 // Lastly, the server responds with the actual content.
9562 MockRead data_reads[] = {
9563 MockRead("HTTP/1.0 200 OK\r\n"),
9564 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9565 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069566 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429567 };
9568
[email protected]31a2bfe2010-02-09 08:03:399569 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9570 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079571 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429572
[email protected]49639fa2011-12-20 23:22:419573 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429574
tfarina42834112016-09-22 13:38:209575 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019576 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429577
9578 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019579 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429580}
9581
bncd16676a2016-07-20 16:23:019582TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429583 HttpRequestInfo request;
9584 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239585 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109586 request.traffic_annotation =
9587 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429588
danakj1fd259a02016-04-16 03:17:099589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279591
[email protected]1c773ea12009-04-28 19:58:429592 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139593 MockWrite("HEAD / HTTP/1.1\r\n"
9594 "Host: www.example.org\r\n"
9595 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429596 };
9597
9598 // Lastly, the server responds with the actual content.
9599 MockRead data_reads[] = {
9600 MockRead("HTTP/1.0 200 OK\r\n"),
9601 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9602 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069603 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429604 };
9605
[email protected]31a2bfe2010-02-09 08:03:399606 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9607 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079608 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429609
[email protected]49639fa2011-12-20 23:22:419610 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429611
tfarina42834112016-09-22 13:38:209612 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429614
9615 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019616 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429617}
9618
bncd16676a2016-07-20 16:23:019619TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429620 HttpRequestInfo request;
9621 request.method = "GET";
bncce36dca22015-04-21 22:11:239622 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429623 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109624 request.traffic_annotation =
9625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429626
danakj1fd259a02016-04-16 03:17:099627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279629
[email protected]1c773ea12009-04-28 19:58:429630 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239631 MockWrite(
9632 "GET / HTTP/1.1\r\n"
9633 "Host: www.example.org\r\n"
9634 "Connection: keep-alive\r\n"
9635 "Pragma: no-cache\r\n"
9636 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429637 };
9638
9639 // Lastly, the server responds with the actual content.
9640 MockRead data_reads[] = {
9641 MockRead("HTTP/1.0 200 OK\r\n"),
9642 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9643 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069644 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429645 };
9646
[email protected]31a2bfe2010-02-09 08:03:399647 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9648 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079649 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429650
[email protected]49639fa2011-12-20 23:22:419651 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429652
tfarina42834112016-09-22 13:38:209653 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429655
9656 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019657 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429658}
9659
bncd16676a2016-07-20 16:23:019660TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429661 HttpRequestInfo request;
9662 request.method = "GET";
bncce36dca22015-04-21 22:11:239663 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429664 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109665 request.traffic_annotation =
9666 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429667
danakj1fd259a02016-04-16 03:17:099668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279670
[email protected]1c773ea12009-04-28 19:58:429671 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239672 MockWrite(
9673 "GET / HTTP/1.1\r\n"
9674 "Host: www.example.org\r\n"
9675 "Connection: keep-alive\r\n"
9676 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429677 };
9678
9679 // Lastly, the server responds with the actual content.
9680 MockRead data_reads[] = {
9681 MockRead("HTTP/1.0 200 OK\r\n"),
9682 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9683 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069684 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429685 };
9686
[email protected]31a2bfe2010-02-09 08:03:399687 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9688 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079689 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429690
[email protected]49639fa2011-12-20 23:22:419691 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429692
tfarina42834112016-09-22 13:38:209693 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429695
9696 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019697 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429698}
9699
bncd16676a2016-07-20 16:23:019700TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429701 HttpRequestInfo request;
9702 request.method = "GET";
bncce36dca22015-04-21 22:11:239703 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439704 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:109705 request.traffic_annotation =
9706 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429707
danakj1fd259a02016-04-16 03:17:099708 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169709 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279710
[email protected]1c773ea12009-04-28 19:58:429711 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239712 MockWrite(
9713 "GET / HTTP/1.1\r\n"
9714 "Host: www.example.org\r\n"
9715 "Connection: keep-alive\r\n"
9716 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429717 };
9718
9719 // Lastly, the server responds with the actual content.
9720 MockRead data_reads[] = {
9721 MockRead("HTTP/1.0 200 OK\r\n"),
9722 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9723 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069724 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429725 };
9726
[email protected]31a2bfe2010-02-09 08:03:399727 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9728 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079729 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429730
[email protected]49639fa2011-12-20 23:22:419731 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429732
tfarina42834112016-09-22 13:38:209733 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429735
9736 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019737 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429738}
9739
bncd16676a2016-07-20 16:23:019740TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479741 HttpRequestInfo request;
9742 request.method = "GET";
bncce36dca22015-04-21 22:11:239743 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439744 request.extra_headers.SetHeader("referer", "www.foo.com");
9745 request.extra_headers.SetHeader("hEllo", "Kitty");
9746 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:109747 request.traffic_annotation =
9748 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479749
danakj1fd259a02016-04-16 03:17:099750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169751 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279752
[email protected]270c6412010-03-29 22:02:479753 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239754 MockWrite(
9755 "GET / HTTP/1.1\r\n"
9756 "Host: www.example.org\r\n"
9757 "Connection: keep-alive\r\n"
9758 "referer: www.foo.com\r\n"
9759 "hEllo: Kitty\r\n"
9760 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479761 };
9762
9763 // Lastly, the server responds with the actual content.
9764 MockRead data_reads[] = {
9765 MockRead("HTTP/1.0 200 OK\r\n"),
9766 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9767 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069768 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479769 };
9770
9771 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9772 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079773 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479774
[email protected]49639fa2011-12-20 23:22:419775 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479776
tfarina42834112016-09-22 13:38:209777 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479779
9780 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019781 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479782}
9783
bncd16676a2016-07-20 16:23:019784TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279785 HttpRequestInfo request;
9786 request.method = "GET";
bncce36dca22015-04-21 22:11:239787 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109788 request.traffic_annotation =
9789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279790
Lily Houghton8c2f97d2018-01-22 05:06:599791 session_deps_.proxy_resolution_service =
9792 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519793 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079794 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029795
danakj1fd259a02016-04-16 03:17:099796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029798
[email protected]3cd17242009-06-23 02:59:029799 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9800 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9801
9802 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239803 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9804 MockWrite(
9805 "GET / HTTP/1.1\r\n"
9806 "Host: www.example.org\r\n"
9807 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029808
9809 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069810 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029811 MockRead("HTTP/1.0 200 OK\r\n"),
9812 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9813 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069814 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029815 };
9816
[email protected]31a2bfe2010-02-09 08:03:399817 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9818 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079819 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029820
[email protected]49639fa2011-12-20 23:22:419821 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029822
tfarina42834112016-09-22 13:38:209823 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029825
9826 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019827 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029828
bnc691fda62016-08-12 00:43:169829 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529830 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029831
tbansal2ecbbc72016-10-06 17:15:479832 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209833 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169834 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209835 TestLoadTimingNotReusedWithPac(load_timing_info,
9836 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9837
[email protected]3cd17242009-06-23 02:59:029838 std::string response_text;
bnc691fda62016-08-12 00:43:169839 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019840 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029841 EXPECT_EQ("Payload", response_text);
9842}
9843
bncd16676a2016-07-20 16:23:019844TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279845 HttpRequestInfo request;
9846 request.method = "GET";
bncce36dca22015-04-21 22:11:239847 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109848 request.traffic_annotation =
9849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279850
Lily Houghton8c2f97d2018-01-22 05:06:599851 session_deps_.proxy_resolution_service =
9852 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519853 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079854 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029855
danakj1fd259a02016-04-16 03:17:099856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169857 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029858
[email protected]3cd17242009-06-23 02:59:029859 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9860 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9861
9862 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239863 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9864 arraysize(write_buffer)),
9865 MockWrite(
9866 "GET / HTTP/1.1\r\n"
9867 "Host: www.example.org\r\n"
9868 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029869
9870 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019871 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9872 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359873 MockRead("HTTP/1.0 200 OK\r\n"),
9874 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9875 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069876 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359877 };
9878
[email protected]31a2bfe2010-02-09 08:03:399879 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9880 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079881 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359882
[email protected]8ddf8322012-02-23 18:08:069883 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079884 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359885
[email protected]49639fa2011-12-20 23:22:419886 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359887
tfarina42834112016-09-22 13:38:209888 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359890
9891 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019892 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359893
[email protected]029c83b62013-01-24 05:28:209894 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169895 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209896 TestLoadTimingNotReusedWithPac(load_timing_info,
9897 CONNECT_TIMING_HAS_SSL_TIMES);
9898
bnc691fda62016-08-12 00:43:169899 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529900 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479901 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359902
9903 std::string response_text;
bnc691fda62016-08-12 00:43:169904 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019905 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359906 EXPECT_EQ("Payload", response_text);
9907}
9908
bncd16676a2016-07-20 16:23:019909TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209910 HttpRequestInfo request;
9911 request.method = "GET";
bncce36dca22015-04-21 22:11:239912 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109913 request.traffic_annotation =
9914 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209915
Lily Houghton8c2f97d2018-01-22 05:06:599916 session_deps_.proxy_resolution_service =
9917 ProxyResolutionService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519918 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079919 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209920
danakj1fd259a02016-04-16 03:17:099921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209923
9924 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9925 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9926
9927 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239928 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9929 MockWrite(
9930 "GET / HTTP/1.1\r\n"
9931 "Host: www.example.org\r\n"
9932 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209933
9934 MockRead data_reads[] = {
9935 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9936 MockRead("HTTP/1.0 200 OK\r\n"),
9937 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9938 MockRead("Payload"),
9939 MockRead(SYNCHRONOUS, OK)
9940 };
9941
9942 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9943 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079944 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209945
9946 TestCompletionCallback callback;
9947
tfarina42834112016-09-22 13:38:209948 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019949 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209950
9951 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019952 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209953
bnc691fda62016-08-12 00:43:169954 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529955 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209956
9957 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169958 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209959 TestLoadTimingNotReused(load_timing_info,
9960 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9961
9962 std::string response_text;
bnc691fda62016-08-12 00:43:169963 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019964 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209965 EXPECT_EQ("Payload", response_text);
9966}
9967
bncd16676a2016-07-20 16:23:019968TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279969 HttpRequestInfo request;
9970 request.method = "GET";
bncce36dca22015-04-21 22:11:239971 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109972 request.traffic_annotation =
9973 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279974
Lily Houghton8c2f97d2018-01-22 05:06:599975 session_deps_.proxy_resolution_service =
9976 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519977 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079978 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359979
danakj1fd259a02016-04-16 03:17:099980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359982
[email protected]e0c27be2009-07-15 13:09:359983 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9984 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379985 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239986 0x05, // Version
9987 0x01, // Command (CONNECT)
9988 0x00, // Reserved.
9989 0x03, // Address type (DOMAINNAME).
9990 0x0F, // Length of domain (15)
9991 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9992 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379993 };
[email protected]e0c27be2009-07-15 13:09:359994 const char kSOCKS5OkResponse[] =
9995 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9996
9997 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239998 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9999 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10000 MockWrite(
10001 "GET / HTTP/1.1\r\n"
10002 "Host: www.example.org\r\n"
10003 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510004
10005 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110006 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10007 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510008 MockRead("HTTP/1.0 200 OK\r\n"),
10009 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10010 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610011 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510012 };
10013
[email protected]31a2bfe2010-02-09 08:03:3910014 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10015 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710016 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510017
[email protected]49639fa2011-12-20 23:22:4110018 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510019
tfarina42834112016-09-22 13:38:2010020 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510022
10023 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110024 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510025
bnc691fda62016-08-12 00:43:1610026 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210027 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710028 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510029
[email protected]029c83b62013-01-24 05:28:2010030 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610031 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010032 TestLoadTimingNotReusedWithPac(load_timing_info,
10033 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10034
[email protected]e0c27be2009-07-15 13:09:3510035 std::string response_text;
bnc691fda62016-08-12 00:43:1610036 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110037 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510038 EXPECT_EQ("Payload", response_text);
10039}
10040
bncd16676a2016-07-20 16:23:0110041TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710042 HttpRequestInfo request;
10043 request.method = "GET";
bncce36dca22015-04-21 22:11:2310044 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010045 request.traffic_annotation =
10046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710047
Lily Houghton8c2f97d2018-01-22 05:06:5910048 session_deps_.proxy_resolution_service =
10049 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:5110050 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710051 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510052
danakj1fd259a02016-04-16 03:17:0910053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610054 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510055
[email protected]e0c27be2009-07-15 13:09:3510056 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10057 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710058 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310059 0x05, // Version
10060 0x01, // Command (CONNECT)
10061 0x00, // Reserved.
10062 0x03, // Address type (DOMAINNAME).
10063 0x0F, // Length of domain (15)
10064 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10065 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710066 };
10067
[email protected]e0c27be2009-07-15 13:09:3510068 const char kSOCKS5OkResponse[] =
10069 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10070
10071 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310072 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10073 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10074 arraysize(kSOCKS5OkRequest)),
10075 MockWrite(
10076 "GET / HTTP/1.1\r\n"
10077 "Host: www.example.org\r\n"
10078 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510079
10080 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110081 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10082 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210083 MockRead("HTTP/1.0 200 OK\r\n"),
10084 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10085 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610086 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210087 };
10088
[email protected]31a2bfe2010-02-09 08:03:3910089 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10090 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710091 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210092
[email protected]8ddf8322012-02-23 18:08:0610093 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210095
[email protected]49639fa2011-12-20 23:22:4110096 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210097
tfarina42834112016-09-22 13:38:2010098 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210100
10101 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110102 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210103
bnc691fda62016-08-12 00:43:1610104 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210105 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710106 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210107
[email protected]029c83b62013-01-24 05:28:2010108 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610109 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010110 TestLoadTimingNotReusedWithPac(load_timing_info,
10111 CONNECT_TIMING_HAS_SSL_TIMES);
10112
[email protected]3cd17242009-06-23 02:59:0210113 std::string response_text;
bnc691fda62016-08-12 00:43:1610114 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110115 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210116 EXPECT_EQ("Payload", response_text);
10117}
10118
[email protected]448d4ca52012-03-04 04:12:2310119namespace {
10120
[email protected]04e5be32009-06-26 20:00:3110121// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610122
10123struct GroupNameTest {
10124 std::string proxy_server;
10125 std::string url;
10126 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810127 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610128};
10129
danakj1fd259a02016-04-16 03:17:0910130std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710131 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910132 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610133
bnc525e175a2016-06-20 12:36:4010134 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310135 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110136 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210137 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110138 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210139 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610140 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610141
10142 return session;
10143}
10144
mmenkee65e7af2015-10-13 17:16:4210145int GroupNameTransactionHelper(const std::string& url,
10146 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610147 HttpRequestInfo request;
10148 request.method = "GET";
10149 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1010150 request.traffic_annotation =
10151 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610152
bnc691fda62016-08-12 00:43:1610153 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710154
[email protected]49639fa2011-12-20 23:22:4110155 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610156
10157 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010158 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610159}
10160
[email protected]448d4ca52012-03-04 04:12:2310161} // namespace
10162
bncd16676a2016-07-20 16:23:0110163TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610164 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310165 {
10166 "", // unused
10167 "http://www.example.org/direct",
10168 "www.example.org:80",
10169 false,
10170 },
10171 {
10172 "", // unused
10173 "http://[2001:1418:13:1::25]/direct",
10174 "[2001:1418:13:1::25]:80",
10175 false,
10176 },
[email protected]04e5be32009-06-26 20:00:3110177
bncce36dca22015-04-21 22:11:2310178 // SSL Tests
10179 {
10180 "", // unused
10181 "https://www.example.org/direct_ssl",
10182 "ssl/www.example.org:443",
10183 true,
10184 },
10185 {
10186 "", // unused
10187 "https://[2001:1418:13:1::25]/direct",
10188 "ssl/[2001:1418:13:1::25]:443",
10189 true,
10190 },
10191 {
10192 "", // unused
bncaa60ff402016-06-22 19:12:4210193 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310194 "ssl/host.with.alternate:443",
10195 true,
10196 },
[email protected]2d731a32010-04-29 01:04:0610197 };
[email protected]2ff8b312010-04-26 22:20:5410198
viettrungluue4a8b882014-10-16 06:17:3810199 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910200 session_deps_.proxy_resolution_service =
10201 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910202 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010203 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610204
mmenkee65e7af2015-10-13 17:16:4210205 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810206 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810207 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310208 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810209 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910210 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210211 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10212 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810213 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610214
10215 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210216 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910217 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810218 EXPECT_EQ(tests[i].expected_group_name,
10219 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910220 } else {
[email protected]e60e47a2010-07-14 03:37:1810221 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810222 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910223 }
10224 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10225 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10226 // When SSL proxy is not in use, socket must be requested from
10227 // |transport_conn_pool|.
10228 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610229 }
[email protected]2d731a32010-04-29 01:04:0610230}
10231
bncd16676a2016-07-20 16:23:0110232TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610233 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310234 {
Matt Menked1eb6d42018-01-17 04:54:0610235 "http_proxy", "http://www.example.org/http_proxy_normal",
10236 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310237 },
[email protected]2d731a32010-04-29 01:04:0610238
bncce36dca22015-04-21 22:11:2310239 // SSL Tests
10240 {
Matt Menked1eb6d42018-01-17 04:54:0610241 "http_proxy", "https://www.example.org/http_connect_ssl",
10242 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310243 },
[email protected]af3490e2010-10-16 21:02:2910244
bncce36dca22015-04-21 22:11:2310245 {
Matt Menked1eb6d42018-01-17 04:54:0610246 "http_proxy", "https://host.with.alternate/direct",
10247 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310248 },
[email protected]45499252013-01-23 17:12:5610249
bncce36dca22015-04-21 22:11:2310250 {
Matt Menked1eb6d42018-01-17 04:54:0610251 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10252 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310253 },
[email protected]2d731a32010-04-29 01:04:0610254 };
10255
viettrungluue4a8b882014-10-16 06:17:3810256 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910257 session_deps_.proxy_resolution_service =
10258 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910259 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010260 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610261
mmenkee65e7af2015-10-13 17:16:4210262 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610263
[email protected]e60e47a2010-07-14 03:37:1810264 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310265 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410266 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310267 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410268 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910269 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910270 mock_pool_manager->SetSocketPoolForHTTPProxy(
10271 proxy_host, base::WrapUnique(http_proxy_pool));
10272 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10273 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810274 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610275
10276 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210277 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810278 if (tests[i].ssl)
10279 EXPECT_EQ(tests[i].expected_group_name,
10280 ssl_conn_pool->last_group_name_received());
10281 else
10282 EXPECT_EQ(tests[i].expected_group_name,
10283 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610284 }
[email protected]2d731a32010-04-29 01:04:0610285}
10286
bncd16676a2016-07-20 16:23:0110287TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610288 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310289 {
10290 "socks4://socks_proxy:1080",
10291 "http://www.example.org/socks4_direct",
10292 "socks4/www.example.org:80",
10293 false,
10294 },
10295 {
10296 "socks5://socks_proxy:1080",
10297 "http://www.example.org/socks5_direct",
10298 "socks5/www.example.org:80",
10299 false,
10300 },
[email protected]2d731a32010-04-29 01:04:0610301
bncce36dca22015-04-21 22:11:2310302 // SSL Tests
10303 {
10304 "socks4://socks_proxy:1080",
10305 "https://www.example.org/socks4_ssl",
10306 "socks4/ssl/www.example.org:443",
10307 true,
10308 },
10309 {
10310 "socks5://socks_proxy:1080",
10311 "https://www.example.org/socks5_ssl",
10312 "socks5/ssl/www.example.org:443",
10313 true,
10314 },
[email protected]af3490e2010-10-16 21:02:2910315
bncce36dca22015-04-21 22:11:2310316 {
10317 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210318 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310319 "socks4/ssl/host.with.alternate:443",
10320 true,
10321 },
[email protected]04e5be32009-06-26 20:00:3110322 };
10323
viettrungluue4a8b882014-10-16 06:17:3810324 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910325 session_deps_.proxy_resolution_service =
10326 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910327 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010328 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210329
mmenkee65e7af2015-10-13 17:16:4210330 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110331
[email protected]e60e47a2010-07-14 03:37:1810332 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310333 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410334 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310335 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410336 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910337 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910338 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10339 proxy_host, base::WrapUnique(socks_conn_pool));
10340 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10341 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810342 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110343
bnc691fda62016-08-12 00:43:1610344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110345
[email protected]2d731a32010-04-29 01:04:0610346 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210347 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810348 if (tests[i].ssl)
10349 EXPECT_EQ(tests[i].expected_group_name,
10350 ssl_conn_pool->last_group_name_received());
10351 else
10352 EXPECT_EQ(tests[i].expected_group_name,
10353 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110354 }
10355}
10356
bncd16676a2016-07-20 16:23:0110357TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710358 HttpRequestInfo request;
10359 request.method = "GET";
bncce36dca22015-04-21 22:11:2310360 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010361 request.traffic_annotation =
10362 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710363
Lily Houghton8c2f97d2018-01-22 05:06:5910364 session_deps_.proxy_resolution_service =
10365 ProxyResolutionService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:3210366
[email protected]69719062010-01-05 20:09:2110367 // This simulates failure resolving all hostnames; that means we will fail
10368 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710369 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210370
danakj1fd259a02016-04-16 03:17:0910371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510373
[email protected]49639fa2011-12-20 23:22:4110374 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510375
tfarina42834112016-09-22 13:38:2010376 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510378
[email protected]9172a982009-06-06 00:30:2510379 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110380 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510381}
10382
[email protected]685af592010-05-11 19:31:2410383// Base test to make sure that when the load flags for a request specify to
10384// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210385void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710386 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710387 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010388 HttpRequestInfo request_info;
10389 request_info.method = "GET";
10390 request_info.load_flags = load_flags;
10391 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010392 request_info.traffic_annotation =
10393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710394
[email protected]a2c2fb92009-07-18 07:31:0410395 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910396 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210397
danakj1fd259a02016-04-16 03:17:0910398 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610399 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810400
bncce36dca22015-04-21 22:11:2310401 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810402 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910403 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010404 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710405 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310406 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010407 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010408 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110411 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810412
10413 // Verify that it was added to host cache, by doing a subsequent async lookup
10414 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010415 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710416 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310417 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010418 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010419 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110420 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810421
bncce36dca22015-04-21 22:11:2310422 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810423 // we can tell if the next lookup hit the cache, or the "network".
10424 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310425 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810426
10427 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10428 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610429 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910430 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710431 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810432
[email protected]3b9cca42009-06-16 01:08:2810433 // Run the request.
tfarina42834112016-09-22 13:38:2010434 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110435 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110436 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810437
10438 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310439 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110440 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810441}
10442
[email protected]685af592010-05-11 19:31:2410443// There are multiple load flags that should trigger the host cache bypass.
10444// Test each in isolation:
bncd16676a2016-07-20 16:23:0110445TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410446 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10447}
10448
bncd16676a2016-07-20 16:23:0110449TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410450 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10451}
10452
bncd16676a2016-07-20 16:23:0110453TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410454 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10455}
10456
[email protected]0877e3d2009-10-17 22:29:5710457// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110458TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710459 HttpRequestInfo request;
10460 request.method = "GET";
10461 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010462 request.traffic_annotation =
10463 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710464
10465 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610466 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710467 };
[email protected]31a2bfe2010-02-09 08:03:3910468 StaticSocketDataProvider data(NULL, 0,
10469 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710470 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710472
[email protected]49639fa2011-12-20 23:22:4110473 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710474
bnc691fda62016-08-12 00:43:1610475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710476
tfarina42834112016-09-22 13:38:2010477 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710479
10480 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110481 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910482
10483 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610484 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910485 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710486}
10487
zmo9528c9f42015-08-04 22:12:0810488// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110489TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710490 HttpRequestInfo request;
10491 request.method = "GET";
10492 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010493 request.traffic_annotation =
10494 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710495
10496 MockRead data_reads[] = {
10497 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610498 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710499 };
10500
[email protected]31a2bfe2010-02-09 08:03:3910501 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710502 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710504
[email protected]49639fa2011-12-20 23:22:4110505 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710506
bnc691fda62016-08-12 00:43:1610507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710508
tfarina42834112016-09-22 13:38:2010509 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710511
10512 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110513 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810514
bnc691fda62016-08-12 00:43:1610515 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210516 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810517
wezca1070932016-05-26 20:30:5210518 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810519 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10520
10521 std::string response_data;
bnc691fda62016-08-12 00:43:1610522 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110523 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810524 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910525
10526 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610527 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910528 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710529}
10530
10531// Make sure that a dropped connection while draining the body for auth
10532// restart does the right thing.
bncd16676a2016-07-20 16:23:0110533TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710534 HttpRequestInfo request;
10535 request.method = "GET";
bncce36dca22015-04-21 22:11:2310536 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010537 request.traffic_annotation =
10538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710539
10540 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310541 MockWrite(
10542 "GET / HTTP/1.1\r\n"
10543 "Host: www.example.org\r\n"
10544 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710545 };
10546
10547 MockRead data_reads1[] = {
10548 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10549 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10550 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10551 MockRead("Content-Length: 14\r\n\r\n"),
10552 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610553 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710554 };
10555
[email protected]31a2bfe2010-02-09 08:03:3910556 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10557 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710558 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710559
bnc691fda62016-08-12 00:43:1610560 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710561 // be issuing -- the final header line contains the credentials.
10562 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310563 MockWrite(
10564 "GET / HTTP/1.1\r\n"
10565 "Host: www.example.org\r\n"
10566 "Connection: keep-alive\r\n"
10567 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710568 };
10569
10570 // Lastly, the server responds with the actual content.
10571 MockRead data_reads2[] = {
10572 MockRead("HTTP/1.1 200 OK\r\n"),
10573 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10574 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610575 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710576 };
10577
[email protected]31a2bfe2010-02-09 08:03:3910578 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10579 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710580 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710582
[email protected]49639fa2011-12-20 23:22:4110583 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710584
bnc691fda62016-08-12 00:43:1610585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010586
tfarina42834112016-09-22 13:38:2010587 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110588 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710589
10590 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110591 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710592
bnc691fda62016-08-12 00:43:1610593 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210594 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410595 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710596
[email protected]49639fa2011-12-20 23:22:4110597 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710598
bnc691fda62016-08-12 00:43:1610599 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710601
10602 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110603 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710604
bnc691fda62016-08-12 00:43:1610605 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210606 ASSERT_TRUE(response);
10607 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710608 EXPECT_EQ(100, response->headers->GetContentLength());
10609}
10610
10611// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110612TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Lily Houghton8c2f97d2018-01-22 05:06:5910613 session_deps_.proxy_resolution_service =
10614 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710615
10616 HttpRequestInfo request;
10617 request.method = "GET";
bncce36dca22015-04-21 22:11:2310618 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010619 request.traffic_annotation =
10620 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710621
10622 MockRead proxy_reads[] = {
10623 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610624 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710625 };
10626
[email protected]31a2bfe2010-02-09 08:03:3910627 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610628 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710629
[email protected]bb88e1d32013-05-03 23:11:0710630 session_deps_.socket_factory->AddSocketDataProvider(&data);
10631 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710632
[email protected]49639fa2011-12-20 23:22:4110633 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710634
[email protected]bb88e1d32013-05-03 23:11:0710635 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710636
danakj1fd259a02016-04-16 03:17:0910637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710639
tfarina42834112016-09-22 13:38:2010640 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710642
10643 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110644 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710645}
10646
bncd16676a2016-07-20 16:23:0110647TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610648 HttpRequestInfo request;
10649 request.method = "GET";
bncce36dca22015-04-21 22:11:2310650 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010651 request.traffic_annotation =
10652 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610653
danakj1fd259a02016-04-16 03:17:0910654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710656
[email protected]e22e1362009-11-23 21:31:1210657 MockRead data_reads[] = {
10658 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610659 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210660 };
[email protected]9492e4a2010-02-24 00:58:4610661
10662 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710663 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610664
[email protected]49639fa2011-12-20 23:22:4110665 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610666
tfarina42834112016-09-22 13:38:2010667 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110668 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610669
robpercival214763f2016-07-01 23:27:0110670 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610671
bnc691fda62016-08-12 00:43:1610672 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210673 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610674
wezca1070932016-05-26 20:30:5210675 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610676 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10677
10678 std::string response_data;
bnc691fda62016-08-12 00:43:1610679 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110680 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210681}
10682
bncd16676a2016-07-20 16:23:0110683TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510684 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210685 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410686 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110687 UploadFileElementReader::ScopedOverridingContentLengthForTests
10688 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310689
danakj1fd259a02016-04-16 03:17:0910690 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910691 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410692 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710693 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210694 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710695
10696 HttpRequestInfo request;
10697 request.method = "POST";
bncce36dca22015-04-21 22:11:2310698 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710699 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010700 request.traffic_annotation =
10701 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710702
danakj1fd259a02016-04-16 03:17:0910703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310705
10706 MockRead data_reads[] = {
10707 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10708 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610709 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310710 };
[email protected]31a2bfe2010-02-09 08:03:3910711 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710712 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310713
[email protected]49639fa2011-12-20 23:22:4110714 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310715
tfarina42834112016-09-22 13:38:2010716 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310718
10719 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110720 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310721
bnc691fda62016-08-12 00:43:1610722 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210723 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310724
maksim.sisove869bf52016-06-23 17:11:5210725 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310726
[email protected]dd3aa792013-07-16 19:10:2310727 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310728}
10729
bncd16676a2016-07-20 16:23:0110730TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510731 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210732 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610733 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810734 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10735 base::WriteFile(temp_file, temp_file_content.c_str(),
10736 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110737 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610738
danakj1fd259a02016-04-16 03:17:0910739 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910740 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410741 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710742 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210743 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710744
10745 HttpRequestInfo request;
10746 request.method = "POST";
bncce36dca22015-04-21 22:11:2310747 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710748 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010749 request.traffic_annotation =
10750 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710751
[email protected]999dd8c2013-11-12 06:45:5410752 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610755
[email protected]999dd8c2013-11-12 06:45:5410756 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710757 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610758
[email protected]49639fa2011-12-20 23:22:4110759 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610760
tfarina42834112016-09-22 13:38:2010761 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610763
10764 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110765 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610766
[email protected]dd3aa792013-07-16 19:10:2310767 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610768}
10769
bncd16676a2016-07-20 16:23:0110770TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310771 class FakeUploadElementReader : public UploadElementReader {
10772 public:
Chris Watkins7a41d3552017-12-01 02:13:2710773 FakeUploadElementReader() = default;
10774 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310775
Matt Menkecc1d3a902018-02-05 18:27:3310776 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310777
10778 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310779 int Init(CompletionOnceCallback callback) override {
10780 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310781 return ERR_IO_PENDING;
10782 }
avibf0746c2015-12-09 19:53:1410783 uint64_t GetContentLength() const override { return 0; }
10784 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010785 int Read(IOBuffer* buf,
10786 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310787 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310788 return ERR_FAILED;
10789 }
10790
10791 private:
Matt Menkecc1d3a902018-02-05 18:27:3310792 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310793 };
10794
10795 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910796 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10797 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210798 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310799
10800 HttpRequestInfo request;
10801 request.method = "POST";
bncce36dca22015-04-21 22:11:2310802 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310803 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010804 request.traffic_annotation =
10805 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310806
danakj1fd259a02016-04-16 03:17:0910807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810808 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910809 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310810
10811 StaticSocketDataProvider data;
10812 session_deps_.socket_factory->AddSocketDataProvider(&data);
10813
10814 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010815 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510817 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310818
10819 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310820 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10821 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310822
10823 // Return Init()'s result after the transaction gets destroyed.
10824 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310825 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310826}
10827
[email protected]aeefc9e82010-02-19 16:18:2710828// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110829TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710830 HttpRequestInfo request;
10831 request.method = "GET";
bncce36dca22015-04-21 22:11:2310832 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010833 request.traffic_annotation =
10834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710835
10836 // First transaction will request a resource and receive a Basic challenge
10837 // with realm="first_realm".
10838 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310839 MockWrite(
10840 "GET / HTTP/1.1\r\n"
10841 "Host: www.example.org\r\n"
10842 "Connection: keep-alive\r\n"
10843 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710844 };
10845 MockRead data_reads1[] = {
10846 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10847 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10848 "\r\n"),
10849 };
10850
bnc691fda62016-08-12 00:43:1610851 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710852 // for first_realm. The server will reject and provide a challenge with
10853 // second_realm.
10854 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310855 MockWrite(
10856 "GET / HTTP/1.1\r\n"
10857 "Host: www.example.org\r\n"
10858 "Connection: keep-alive\r\n"
10859 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10860 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710861 };
10862 MockRead data_reads2[] = {
10863 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10864 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10865 "\r\n"),
10866 };
10867
10868 // This again fails, and goes back to first_realm. Make sure that the
10869 // entry is removed from cache.
10870 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310871 MockWrite(
10872 "GET / HTTP/1.1\r\n"
10873 "Host: www.example.org\r\n"
10874 "Connection: keep-alive\r\n"
10875 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10876 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710877 };
10878 MockRead data_reads3[] = {
10879 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10880 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10881 "\r\n"),
10882 };
10883
10884 // Try one last time (with the correct password) and get the resource.
10885 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310886 MockWrite(
10887 "GET / HTTP/1.1\r\n"
10888 "Host: www.example.org\r\n"
10889 "Connection: keep-alive\r\n"
10890 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10891 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710892 };
10893 MockRead data_reads4[] = {
10894 MockRead("HTTP/1.1 200 OK\r\n"
10895 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010896 "Content-Length: 5\r\n"
10897 "\r\n"
10898 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710899 };
10900
10901 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10902 data_writes1, arraysize(data_writes1));
10903 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10904 data_writes2, arraysize(data_writes2));
10905 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10906 data_writes3, arraysize(data_writes3));
10907 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10908 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710909 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10910 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10911 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10912 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710913
[email protected]49639fa2011-12-20 23:22:4110914 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710915
danakj1fd259a02016-04-16 03:17:0910916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010918
[email protected]aeefc9e82010-02-19 16:18:2710919 // Issue the first request with Authorize headers. There should be a
10920 // password prompt for first_realm waiting to be filled in after the
10921 // transaction completes.
tfarina42834112016-09-22 13:38:2010922 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710924 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110925 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610926 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210927 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410928 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210929 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410930 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310931 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410932 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910933 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710934
10935 // Issue the second request with an incorrect password. There should be a
10936 // password prompt for second_realm waiting to be filled in after the
10937 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110938 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610939 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10940 callback2.callback());
robpercival214763f2016-07-01 23:27:0110941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710942 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110943 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610944 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210945 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410946 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210947 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410948 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310949 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410950 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910951 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710952
10953 // Issue the third request with another incorrect password. There should be
10954 // a password prompt for first_realm waiting to be filled in. If the password
10955 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10956 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110957 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610958 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10959 callback3.callback());
robpercival214763f2016-07-01 23:27:0110960 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710961 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110962 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610963 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210964 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410965 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210966 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410967 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310968 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410969 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910970 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710971
10972 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110973 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610974 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10975 callback4.callback());
robpercival214763f2016-07-01 23:27:0110976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710977 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110978 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610979 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210980 ASSERT_TRUE(response);
10981 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710982}
10983
Bence Béky230ac612017-08-30 19:17:0810984// Regression test for https://crbug.com/754395.
10985TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10986 MockRead data_reads[] = {
10987 MockRead("HTTP/1.1 200 OK\r\n"),
10988 MockRead(kAlternativeServiceHttpHeader),
10989 MockRead("\r\n"),
10990 MockRead("hello world"),
10991 MockRead(SYNCHRONOUS, OK),
10992 };
10993
10994 HttpRequestInfo request;
10995 request.method = "GET";
10996 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010997 request.traffic_annotation =
10998 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0810999
11000 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11001 session_deps_.socket_factory->AddSocketDataProvider(&data);
11002
11003 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911004 ssl.ssl_info.cert =
11005 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11006 ASSERT_TRUE(ssl.ssl_info.cert);
11007 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811008 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11009
11010 TestCompletionCallback callback;
11011
11012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11014
11015 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11017
11018 url::SchemeHostPort test_server(request.url);
11019 HttpServerProperties* http_server_properties =
11020 session->http_server_properties();
11021 EXPECT_TRUE(
11022 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11023
11024 EXPECT_THAT(callback.WaitForResult(), IsOk());
11025
11026 const HttpResponseInfo* response = trans.GetResponseInfo();
11027 ASSERT_TRUE(response);
11028 ASSERT_TRUE(response->headers);
11029 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11030 EXPECT_FALSE(response->was_fetched_via_spdy);
11031 EXPECT_FALSE(response->was_alpn_negotiated);
11032
11033 std::string response_data;
11034 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11035 EXPECT_EQ("hello world", response_data);
11036
11037 EXPECT_TRUE(
11038 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11039}
11040
bncd16676a2016-07-20 16:23:0111041TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211042 MockRead data_reads[] = {
11043 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311044 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211045 MockRead("\r\n"),
11046 MockRead("hello world"),
11047 MockRead(SYNCHRONOUS, OK),
11048 };
11049
11050 HttpRequestInfo request;
11051 request.method = "GET";
bncb26024382016-06-29 02:39:4511052 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011053 request.traffic_annotation =
11054 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211055
11056 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211057 session_deps_.socket_factory->AddSocketDataProvider(&data);
11058
bncb26024382016-06-29 02:39:4511059 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911060 ssl.ssl_info.cert =
11061 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11062 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11064
bncc958faa2015-07-31 18:14:5211065 TestCompletionCallback callback;
11066
danakj1fd259a02016-04-16 03:17:0911067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211069
tfarina42834112016-09-22 13:38:2011070 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211072
bncb26024382016-06-29 02:39:4511073 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011074 HttpServerProperties* http_server_properties =
11075 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411076 EXPECT_TRUE(
11077 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211078
robpercival214763f2016-07-01 23:27:0111079 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211080
bnc691fda62016-08-12 00:43:1611081 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211082 ASSERT_TRUE(response);
11083 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211084 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11085 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211086 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211087
11088 std::string response_data;
bnc691fda62016-08-12 00:43:1611089 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211090 EXPECT_EQ("hello world", response_data);
11091
zhongyic4de03032017-05-19 04:07:3411092 AlternativeServiceInfoVector alternative_service_info_vector =
11093 http_server_properties->GetAlternativeServiceInfos(test_server);
11094 ASSERT_EQ(1u, alternative_service_info_vector.size());
11095 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11096 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411097 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211098}
11099
bnce3dd56f2016-06-01 10:37:1111100// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111101TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111102 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111103 MockRead data_reads[] = {
11104 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311105 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111106 MockRead("\r\n"),
11107 MockRead("hello world"),
11108 MockRead(SYNCHRONOUS, OK),
11109 };
11110
11111 HttpRequestInfo request;
11112 request.method = "GET";
11113 request.url = GURL("http://www.example.org/");
11114 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011115 request.traffic_annotation =
11116 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111117
11118 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11119 session_deps_.socket_factory->AddSocketDataProvider(&data);
11120
11121 TestCompletionCallback callback;
11122
11123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611124 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111125
11126 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011127 HttpServerProperties* http_server_properties =
11128 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411129 EXPECT_TRUE(
11130 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111131
tfarina42834112016-09-22 13:38:2011132 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111133 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11134 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111135
bnc691fda62016-08-12 00:43:1611136 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111137 ASSERT_TRUE(response);
11138 ASSERT_TRUE(response->headers);
11139 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11140 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211141 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111142
11143 std::string response_data;
bnc691fda62016-08-12 00:43:1611144 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111145 EXPECT_EQ("hello world", response_data);
11146
zhongyic4de03032017-05-19 04:07:3411147 EXPECT_TRUE(
11148 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111149}
11150
bnca86731e2017-04-17 12:31:2811151// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511152// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111153TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511154 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811155 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511156
bnc8bef8da22016-05-30 01:28:2511157 HttpRequestInfo request;
11158 request.method = "GET";
bncb26024382016-06-29 02:39:4511159 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511160 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011161 request.traffic_annotation =
11162 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511163
11164 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11165 StaticSocketDataProvider first_data;
11166 first_data.set_connect_data(mock_connect);
11167 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511168 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611169 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511171
11172 MockRead data_reads[] = {
11173 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11174 MockRead(ASYNC, OK),
11175 };
11176 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11177 0);
11178 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11179
11180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11181
bnc525e175a2016-06-20 12:36:4011182 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511183 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111184 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11185 444);
bnc8bef8da22016-05-30 01:28:2511186 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111187 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511188 url::SchemeHostPort(request.url), alternative_service, expiration);
11189
bnc691fda62016-08-12 00:43:1611190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511191 TestCompletionCallback callback;
11192
tfarina42834112016-09-22 13:38:2011193 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511194 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111195 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511196}
11197
bnce3dd56f2016-06-01 10:37:1111198// Regression test for https://crbug.com/615497:
11199// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111200TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111201 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111202 HttpRequestInfo request;
11203 request.method = "GET";
11204 request.url = GURL("http://www.example.org/");
11205 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011206 request.traffic_annotation =
11207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111208
11209 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11210 StaticSocketDataProvider first_data;
11211 first_data.set_connect_data(mock_connect);
11212 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11213
11214 MockRead data_reads[] = {
11215 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11216 MockRead(ASYNC, OK),
11217 };
11218 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11219 0);
11220 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11221
11222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11223
bnc525e175a2016-06-20 12:36:4011224 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111225 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111226 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111227 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111228 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111229 url::SchemeHostPort(request.url), alternative_service, expiration);
11230
bnc691fda62016-08-12 00:43:1611231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111232 TestCompletionCallback callback;
11233
tfarina42834112016-09-22 13:38:2011234 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111235 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111236 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111237}
11238
bncd16676a2016-07-20 16:23:0111239TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811240 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011242 HttpServerProperties* http_server_properties =
11243 session->http_server_properties();
bncb26024382016-06-29 02:39:4511244 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111245 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811246 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111247 http_server_properties->SetQuicAlternativeService(
11248 test_server, alternative_service, expiration,
11249 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411250 EXPECT_EQ(
11251 1u,
11252 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811253
11254 // Send a clear header.
11255 MockRead data_reads[] = {
11256 MockRead("HTTP/1.1 200 OK\r\n"),
11257 MockRead("Alt-Svc: clear\r\n"),
11258 MockRead("\r\n"),
11259 MockRead("hello world"),
11260 MockRead(SYNCHRONOUS, OK),
11261 };
11262 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
11263 session_deps_.socket_factory->AddSocketDataProvider(&data);
11264
bncb26024382016-06-29 02:39:4511265 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911266 ssl.ssl_info.cert =
11267 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11268 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11270
bnc4f575852015-10-14 18:35:0811271 HttpRequestInfo request;
11272 request.method = "GET";
bncb26024382016-06-29 02:39:4511273 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011274 request.traffic_annotation =
11275 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811276
11277 TestCompletionCallback callback;
11278
bnc691fda62016-08-12 00:43:1611279 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811280
tfarina42834112016-09-22 13:38:2011281 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111282 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811283
bnc691fda62016-08-12 00:43:1611284 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211285 ASSERT_TRUE(response);
11286 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811287 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11288 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211289 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811290
11291 std::string response_data;
bnc691fda62016-08-12 00:43:1611292 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811293 EXPECT_EQ("hello world", response_data);
11294
zhongyic4de03032017-05-19 04:07:3411295 EXPECT_TRUE(
11296 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811297}
11298
bncd16676a2016-07-20 16:23:0111299TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211300 MockRead data_reads[] = {
11301 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311302 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11303 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211304 MockRead("hello world"),
11305 MockRead(SYNCHRONOUS, OK),
11306 };
11307
11308 HttpRequestInfo request;
11309 request.method = "GET";
bncb26024382016-06-29 02:39:4511310 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011311 request.traffic_annotation =
11312 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211313
11314 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211315 session_deps_.socket_factory->AddSocketDataProvider(&data);
11316
bncb26024382016-06-29 02:39:4511317 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911318 ssl.ssl_info.cert =
11319 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11320 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511321 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11322
bncc958faa2015-07-31 18:14:5211323 TestCompletionCallback callback;
11324
danakj1fd259a02016-04-16 03:17:0911325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211327
tfarina42834112016-09-22 13:38:2011328 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211330
bncb26024382016-06-29 02:39:4511331 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011332 HttpServerProperties* http_server_properties =
11333 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411334 EXPECT_TRUE(
11335 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211336
robpercival214763f2016-07-01 23:27:0111337 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211338
bnc691fda62016-08-12 00:43:1611339 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211340 ASSERT_TRUE(response);
11341 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211342 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11343 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211344 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211345
11346 std::string response_data;
bnc691fda62016-08-12 00:43:1611347 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211348 EXPECT_EQ("hello world", response_data);
11349
zhongyic4de03032017-05-19 04:07:3411350 AlternativeServiceInfoVector alternative_service_info_vector =
11351 http_server_properties->GetAlternativeServiceInfos(test_server);
11352 ASSERT_EQ(2u, alternative_service_info_vector.size());
11353
11354 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11355 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411356 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411357 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11358 1234);
11359 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411360 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211361}
11362
bncd16676a2016-07-20 16:23:0111363TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611364 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211365 HostPortPair alternative("alternative.example.org", 443);
11366 std::string origin_url = "https://origin.example.org:443";
11367 std::string alternative_url = "https://alternative.example.org:443";
11368
11369 // Negotiate HTTP/1.1 with alternative.example.org.
11370 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611371 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11373
11374 // HTTP/1.1 data for request.
11375 MockWrite http_writes[] = {
11376 MockWrite("GET / HTTP/1.1\r\n"
11377 "Host: alternative.example.org\r\n"
11378 "Connection: keep-alive\r\n\r\n"),
11379 };
11380
11381 MockRead http_reads[] = {
11382 MockRead("HTTP/1.1 200 OK\r\n"
11383 "Content-Type: text/html; charset=iso-8859-1\r\n"
11384 "Content-Length: 40\r\n\r\n"
11385 "first HTTP/1.1 response from alternative"),
11386 };
11387 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11388 http_writes, arraysize(http_writes));
11389 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11390
11391 StaticSocketDataProvider data_refused;
11392 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11393 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11394
zhongyi3d4a55e72016-04-22 20:36:4611395 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911396 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011397 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211398 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111399 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211400 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111401 http_server_properties->SetQuicAlternativeService(
11402 server, alternative_service, expiration,
11403 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211404 // Mark the QUIC alternative service as broken.
11405 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11406
zhongyi48704c182015-12-07 07:52:0211407 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211409 request.method = "GET";
11410 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011411 request.traffic_annotation =
11412 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11413
zhongyi48704c182015-12-07 07:52:0211414 TestCompletionCallback callback;
11415 NetErrorDetails details;
11416 EXPECT_FALSE(details.quic_broken);
11417
tfarina42834112016-09-22 13:38:2011418 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611419 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211420 EXPECT_TRUE(details.quic_broken);
11421}
11422
bncd16676a2016-07-20 16:23:0111423TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611424 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211425 HostPortPair alternative1("alternative1.example.org", 443);
11426 HostPortPair alternative2("alternative2.example.org", 443);
11427 std::string origin_url = "https://origin.example.org:443";
11428 std::string alternative_url1 = "https://alternative1.example.org:443";
11429 std::string alternative_url2 = "https://alternative2.example.org:443";
11430
11431 // Negotiate HTTP/1.1 with alternative1.example.org.
11432 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611433 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11435
11436 // HTTP/1.1 data for request.
11437 MockWrite http_writes[] = {
11438 MockWrite("GET / HTTP/1.1\r\n"
11439 "Host: alternative1.example.org\r\n"
11440 "Connection: keep-alive\r\n\r\n"),
11441 };
11442
11443 MockRead http_reads[] = {
11444 MockRead("HTTP/1.1 200 OK\r\n"
11445 "Content-Type: text/html; charset=iso-8859-1\r\n"
11446 "Content-Length: 40\r\n\r\n"
11447 "first HTTP/1.1 response from alternative1"),
11448 };
11449 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11450 http_writes, arraysize(http_writes));
11451 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11452
11453 StaticSocketDataProvider data_refused;
11454 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11455 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11456
danakj1fd259a02016-04-16 03:17:0911457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011458 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211459 session->http_server_properties();
11460
zhongyi3d4a55e72016-04-22 20:36:4611461 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211462 AlternativeServiceInfoVector alternative_service_info_vector;
11463 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11464
bnc3472afd2016-11-17 15:27:2111465 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111466 alternative_service_info_vector.push_back(
11467 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11468 alternative_service1, expiration,
11469 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111470 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111471 alternative_service_info_vector.push_back(
11472 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11473 alternative_service2, expiration,
11474 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211475
11476 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611477 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211478
11479 // Mark one of the QUIC alternative service as broken.
11480 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411481 EXPECT_EQ(2u,
11482 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211483
zhongyi48704c182015-12-07 07:52:0211484 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211486 request.method = "GET";
11487 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011488 request.traffic_annotation =
11489 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11490
zhongyi48704c182015-12-07 07:52:0211491 TestCompletionCallback callback;
11492 NetErrorDetails details;
11493 EXPECT_FALSE(details.quic_broken);
11494
tfarina42834112016-09-22 13:38:2011495 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611496 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211497 EXPECT_FALSE(details.quic_broken);
11498}
11499
bncd16676a2016-07-20 16:23:0111500TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211501 HttpRequestInfo request;
11502 request.method = "GET";
bncb26024382016-06-29 02:39:4511503 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011504 request.traffic_annotation =
11505 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211506
[email protected]d973e99a2012-02-17 21:02:3611507 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211508 StaticSocketDataProvider first_data;
11509 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711510 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511511 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611512 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211514
11515 MockRead data_reads[] = {
11516 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11517 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611518 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211519 };
11520 StaticSocketDataProvider second_data(
11521 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711522 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211523
danakj1fd259a02016-04-16 03:17:0911524 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211525
bnc525e175a2016-06-20 12:36:4011526 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311527 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611528 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111529 // Port must be < 1024, or the header will be ignored (since initial port was
11530 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111531 // Port is ignored by MockConnect anyway.
11532 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11533 666);
bnc7dc7e1b42015-07-28 14:43:1211534 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111535 http_server_properties->SetHttp2AlternativeService(
11536 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211537
bnc691fda62016-08-12 00:43:1611538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111539 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211540
tfarina42834112016-09-22 13:38:2011541 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111542 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11543 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211544
bnc691fda62016-08-12 00:43:1611545 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211546 ASSERT_TRUE(response);
11547 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211548 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11549
11550 std::string response_data;
bnc691fda62016-08-12 00:43:1611551 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211552 EXPECT_EQ("hello world", response_data);
11553
zhongyic4de03032017-05-19 04:07:3411554 const AlternativeServiceInfoVector alternative_service_info_vector =
11555 http_server_properties->GetAlternativeServiceInfos(server);
11556 ASSERT_EQ(1u, alternative_service_info_vector.size());
11557 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411558 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411559 EXPECT_TRUE(
11560 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211561}
11562
bnc55ff9da2015-08-19 18:42:3511563// Ensure that we are not allowed to redirect traffic via an alternate protocol
11564// to an unrestricted (port >= 1024) when the original traffic was on a
11565// restricted port (port < 1024). Ensure that we can redirect in all other
11566// cases.
bncd16676a2016-07-20 16:23:0111567TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111568 HttpRequestInfo restricted_port_request;
11569 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511570 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111571 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011572 restricted_port_request.traffic_annotation =
11573 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111574
[email protected]d973e99a2012-02-17 21:02:3611575 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111576 StaticSocketDataProvider first_data;
11577 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711578 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111579
11580 MockRead data_reads[] = {
11581 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11582 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611583 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111584 };
11585 StaticSocketDataProvider second_data(
11586 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711587 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511588 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611589 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111591
danakj1fd259a02016-04-16 03:17:0911592 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111593
bnc525e175a2016-06-20 12:36:4011594 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311595 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111596 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111597 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11598 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211599 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111600 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611601 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011602 expiration);
[email protected]3912662a32011-10-04 00:51:1111603
bnc691fda62016-08-12 00:43:1611604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111605 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111606
tfarina42834112016-09-22 13:38:2011607 int rv = trans.Start(&restricted_port_request, callback.callback(),
11608 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111610 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111611 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911612}
[email protected]3912662a32011-10-04 00:51:1111613
bnc55ff9da2015-08-19 18:42:3511614// Ensure that we are allowed to redirect traffic via an alternate protocol to
11615// an unrestricted (port >= 1024) when the original traffic was on a restricted
11616// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111617TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711618 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911619
11620 HttpRequestInfo restricted_port_request;
11621 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511622 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911623 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011624 restricted_port_request.traffic_annotation =
11625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911626
11627 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11628 StaticSocketDataProvider first_data;
11629 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711630 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911631
11632 MockRead data_reads[] = {
11633 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11634 MockRead("hello world"),
11635 MockRead(ASYNC, OK),
11636 };
11637 StaticSocketDataProvider second_data(
11638 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711639 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511640 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611641 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511642 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911643
danakj1fd259a02016-04-16 03:17:0911644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911645
bnc525e175a2016-06-20 12:36:4011646 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911647 session->http_server_properties();
11648 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111649 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11650 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211651 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111652 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611653 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011654 expiration);
[email protected]c54c6962013-02-01 04:53:1911655
bnc691fda62016-08-12 00:43:1611656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911657 TestCompletionCallback callback;
11658
tfarina42834112016-09-22 13:38:2011659 EXPECT_EQ(ERR_IO_PENDING,
11660 trans.Start(&restricted_port_request, callback.callback(),
11661 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911662 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111663 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111664}
11665
bnc55ff9da2015-08-19 18:42:3511666// Ensure that we are not allowed to redirect traffic via an alternate protocol
11667// to an unrestricted (port >= 1024) when the original traffic was on a
11668// restricted port (port < 1024). Ensure that we can redirect in all other
11669// cases.
bncd16676a2016-07-20 16:23:0111670TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111671 HttpRequestInfo restricted_port_request;
11672 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511673 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111674 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011675 restricted_port_request.traffic_annotation =
11676 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111677
[email protected]d973e99a2012-02-17 21:02:3611678 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111679 StaticSocketDataProvider first_data;
11680 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711681 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111682
11683 MockRead data_reads[] = {
11684 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11685 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611686 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111687 };
11688 StaticSocketDataProvider second_data(
11689 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711690 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111691
bncb26024382016-06-29 02:39:4511692 SSLSocketDataProvider ssl(ASYNC, OK);
11693 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11694
danakj1fd259a02016-04-16 03:17:0911695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111696
bnc525e175a2016-06-20 12:36:4011697 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311698 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111699 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111700 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11701 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211702 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111703 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611704 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011705 expiration);
[email protected]3912662a32011-10-04 00:51:1111706
bnc691fda62016-08-12 00:43:1611707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111708 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111709
tfarina42834112016-09-22 13:38:2011710 int rv = trans.Start(&restricted_port_request, callback.callback(),
11711 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111713 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111714 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111715}
11716
bnc55ff9da2015-08-19 18:42:3511717// Ensure that we are not allowed to redirect traffic via an alternate protocol
11718// to an unrestricted (port >= 1024) when the original traffic was on a
11719// restricted port (port < 1024). Ensure that we can redirect in all other
11720// cases.
bncd16676a2016-07-20 16:23:0111721TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111722 HttpRequestInfo unrestricted_port_request;
11723 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511724 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111725 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011726 unrestricted_port_request.traffic_annotation =
11727 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111728
[email protected]d973e99a2012-02-17 21:02:3611729 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111730 StaticSocketDataProvider first_data;
11731 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711732 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111733
11734 MockRead data_reads[] = {
11735 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11736 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611737 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111738 };
11739 StaticSocketDataProvider second_data(
11740 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711741 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511742 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611743 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111745
danakj1fd259a02016-04-16 03:17:0911746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111747
bnc525e175a2016-06-20 12:36:4011748 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311749 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111750 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111751 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11752 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211753 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111754 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611755 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011756 expiration);
[email protected]3912662a32011-10-04 00:51:1111757
bnc691fda62016-08-12 00:43:1611758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111759 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111760
bnc691fda62016-08-12 00:43:1611761 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011762 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111764 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111765 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111766}
11767
bnc55ff9da2015-08-19 18:42:3511768// Ensure that we are not allowed to redirect traffic via an alternate protocol
11769// to an unrestricted (port >= 1024) when the original traffic was on a
11770// restricted port (port < 1024). Ensure that we can redirect in all other
11771// cases.
bncd16676a2016-07-20 16:23:0111772TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111773 HttpRequestInfo unrestricted_port_request;
11774 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511775 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111776 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011777 unrestricted_port_request.traffic_annotation =
11778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111779
[email protected]d973e99a2012-02-17 21:02:3611780 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111781 StaticSocketDataProvider first_data;
11782 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711783 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111784
11785 MockRead data_reads[] = {
11786 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11787 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611788 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111789 };
11790 StaticSocketDataProvider second_data(
11791 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711792 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111793
bncb26024382016-06-29 02:39:4511794 SSLSocketDataProvider ssl(ASYNC, OK);
11795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11796
danakj1fd259a02016-04-16 03:17:0911797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111798
bnc525e175a2016-06-20 12:36:4011799 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311800 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211801 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111802 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11803 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211804 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111805 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611806 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011807 expiration);
[email protected]3912662a32011-10-04 00:51:1111808
bnc691fda62016-08-12 00:43:1611809 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111810 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111811
bnc691fda62016-08-12 00:43:1611812 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011813 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111815 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111816 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111817}
11818
bnc55ff9da2015-08-19 18:42:3511819// Ensure that we are not allowed to redirect traffic via an alternate protocol
11820// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11821// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111822TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211823 HttpRequestInfo request;
11824 request.method = "GET";
bncce36dca22015-04-21 22:11:2311825 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011826 request.traffic_annotation =
11827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211828
11829 // The alternate protocol request will error out before we attempt to connect,
11830 // so only the standard HTTP request will try to connect.
11831 MockRead data_reads[] = {
11832 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11833 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611834 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211835 };
11836 StaticSocketDataProvider data(
11837 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711838 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211839
danakj1fd259a02016-04-16 03:17:0911840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211841
bnc525e175a2016-06-20 12:36:4011842 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211843 session->http_server_properties();
11844 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111845 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11846 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211847 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111848 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611849 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211850
bnc691fda62016-08-12 00:43:1611851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211852 TestCompletionCallback callback;
11853
tfarina42834112016-09-22 13:38:2011854 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111855 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211856 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111857 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211858
bnc691fda62016-08-12 00:43:1611859 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211860 ASSERT_TRUE(response);
11861 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211862 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11863
11864 std::string response_data;
bnc691fda62016-08-12 00:43:1611865 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211866 EXPECT_EQ("hello world", response_data);
11867}
11868
bncd16676a2016-07-20 16:23:0111869TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411870 HttpRequestInfo request;
11871 request.method = "GET";
bncb26024382016-06-29 02:39:4511872 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011873 request.traffic_annotation =
11874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411875
11876 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211877 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311878 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211879 MockRead("\r\n"),
11880 MockRead("hello world"),
11881 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11882 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411883
11884 StaticSocketDataProvider first_transaction(
11885 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711886 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511887 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611888 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411890
bnc032658ba2016-09-26 18:17:1511891 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411892
bncdf80d44fd2016-07-15 20:27:4111893 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511894 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111895 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411896
bnc42331402016-07-25 13:36:1511897 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111898 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411899 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111900 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411901 };
11902
rch8e6c6c42015-05-01 14:05:1311903 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11904 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711905 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411906
[email protected]d973e99a2012-02-17 21:02:3611907 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511908 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11909 NULL, 0, NULL, 0);
11910 hanging_non_alternate_protocol_socket.set_connect_data(
11911 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711912 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511913 &hanging_non_alternate_protocol_socket);
11914
[email protected]49639fa2011-12-20 23:22:4111915 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411916
danakj1fd259a02016-04-16 03:17:0911917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811918 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911919 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411920
tfarina42834112016-09-22 13:38:2011921 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11923 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411924
11925 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211926 ASSERT_TRUE(response);
11927 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411928 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11929
11930 std::string response_data;
robpercival214763f2016-07-01 23:27:0111931 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411932 EXPECT_EQ("hello world", response_data);
11933
bnc87dcefc2017-05-25 12:47:5811934 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911935 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411936
tfarina42834112016-09-22 13:38:2011937 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11939 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411940
11941 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211942 ASSERT_TRUE(response);
11943 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211944 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311945 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211946 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411947
robpercival214763f2016-07-01 23:27:0111948 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411949 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411950}
11951
bncd16676a2016-07-20 16:23:0111952TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511953 HttpRequestInfo request;
11954 request.method = "GET";
bncb26024382016-06-29 02:39:4511955 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011956 request.traffic_annotation =
11957 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511958
bncb26024382016-06-29 02:39:4511959 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511960 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211961 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311962 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211963 MockRead("\r\n"),
11964 MockRead("hello world"),
11965 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11966 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511967 };
11968
bncb26024382016-06-29 02:39:4511969 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11970 0);
11971 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511972
bncb26024382016-06-29 02:39:4511973 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911974 ssl_http11.ssl_info.cert =
11975 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11976 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511977 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11978
11979 // Second transaction starts an alternative and a non-alternative Job.
11980 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611981 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811982 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11983 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811984 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11985
11986 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11987 hanging_socket2.set_connect_data(never_finishing_connect);
11988 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511989
bncb26024382016-06-29 02:39:4511990 // Third transaction starts an alternative and a non-alternative job.
11991 // The non-alternative job hangs, but the alternative one succeeds.
11992 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111993 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511994 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111995 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511996 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511997 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111998 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511999 };
bnc42331402016-07-25 13:36:1512000 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112001 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512002 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112003 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512004 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112005 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12006 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312007 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512008 };
12009
rch8e6c6c42015-05-01 14:05:1312010 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12011 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712012 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512013
bnc032658ba2016-09-26 18:17:1512014 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512015
mmenkecc2298e2015-12-07 18:20:1812016 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
12017 hanging_socket3.set_connect_data(never_finishing_connect);
12018 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512019
danakj1fd259a02016-04-16 03:17:0912020 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112021 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012022 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512023
tfarina42834112016-09-22 13:38:2012024 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112025 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12026 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512027
12028 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212029 ASSERT_TRUE(response);
12030 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512031 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12032
12033 std::string response_data;
robpercival214763f2016-07-01 23:27:0112034 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512035 EXPECT_EQ("hello world", response_data);
12036
[email protected]49639fa2011-12-20 23:22:4112037 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012038 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012039 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512041
[email protected]49639fa2011-12-20 23:22:4112042 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012043 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012044 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512046
robpercival214763f2016-07-01 23:27:0112047 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12048 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512049
12050 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212051 ASSERT_TRUE(response);
12052 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212053 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512054 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212055 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112056 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512057 EXPECT_EQ("hello!", response_data);
12058
12059 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212060 ASSERT_TRUE(response);
12061 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212062 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512063 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212064 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112065 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512066 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512067}
12068
bncd16676a2016-07-20 16:23:0112069TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512070 HttpRequestInfo request;
12071 request.method = "GET";
bncb26024382016-06-29 02:39:4512072 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012073 request.traffic_annotation =
12074 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512075
12076 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212077 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312078 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212079 MockRead("\r\n"),
12080 MockRead("hello world"),
12081 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12082 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512083 };
12084
12085 StaticSocketDataProvider first_transaction(
12086 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712087 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512088
[email protected]8ddf8322012-02-23 18:08:0612089 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912090 ssl.ssl_info.cert =
12091 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12092 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512094
[email protected]d973e99a2012-02-17 21:02:3612095 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512096 StaticSocketDataProvider hanging_alternate_protocol_socket(
12097 NULL, 0, NULL, 0);
12098 hanging_alternate_protocol_socket.set_connect_data(
12099 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712100 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512101 &hanging_alternate_protocol_socket);
12102
bncb26024382016-06-29 02:39:4512103 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1812104 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
12105 NULL, 0);
12106 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512107 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512108
[email protected]49639fa2011-12-20 23:22:4112109 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512110
danakj1fd259a02016-04-16 03:17:0912111 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812112 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912113 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512114
tfarina42834112016-09-22 13:38:2012115 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12117 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512118
12119 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212120 ASSERT_TRUE(response);
12121 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512122 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12123
12124 std::string response_data;
robpercival214763f2016-07-01 23:27:0112125 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512126 EXPECT_EQ("hello world", response_data);
12127
bnc87dcefc2017-05-25 12:47:5812128 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912129 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512130
tfarina42834112016-09-22 13:38:2012131 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12133 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512134
12135 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212136 ASSERT_TRUE(response);
12137 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512138 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12139 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212140 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512141
robpercival214763f2016-07-01 23:27:0112142 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512143 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512144}
12145
[email protected]631f1322010-04-30 17:59:1112146class CapturingProxyResolver : public ProxyResolver {
12147 public:
Chris Watkins7a41d3552017-12-01 02:13:2712148 CapturingProxyResolver() = default;
12149 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112150
dchengb03027d2014-10-21 12:00:2012151 int GetProxyForURL(const GURL& url,
12152 ProxyInfo* results,
12153 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512154 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012155 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012156 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12157 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212158 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112159 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212160 return OK;
[email protected]631f1322010-04-30 17:59:1112161 }
12162
[email protected]24476402010-07-20 20:55:1712163 const std::vector<GURL>& resolved() const { return resolved_; }
12164
12165 private:
[email protected]631f1322010-04-30 17:59:1112166 std::vector<GURL> resolved_;
12167
12168 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12169};
12170
sammce64b2362015-04-29 03:50:2312171class CapturingProxyResolverFactory : public ProxyResolverFactory {
12172 public:
12173 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12174 : ProxyResolverFactory(false), resolver_(resolver) {}
12175
Lily Houghton99597862018-03-07 16:40:4212176 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12177 std::unique_ptr<ProxyResolver>* resolver,
12178 const net::CompletionCallback& callback,
12179 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912180 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312181 return OK;
12182 }
12183
12184 private:
12185 ProxyResolver* resolver_;
12186};
12187
bnc2e884782016-08-11 19:45:1912188// Test that proxy is resolved using the origin url,
12189// regardless of the alternative server.
12190TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12191 // Configure proxy to bypass www.example.org, which is the origin URL.
12192 ProxyConfig proxy_config;
12193 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12194 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
12195 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1912196 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1912197
12198 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912199 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912200 &capturing_proxy_resolver);
12201
12202 TestNetLog net_log;
12203
Lily Houghton8c2f97d2018-01-22 05:06:5912204 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1912205 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12206 &net_log);
12207
12208 session_deps_.net_log = &net_log;
12209
12210 // Configure alternative service with a hostname that is not bypassed by the
12211 // proxy.
12212 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12213 HttpServerProperties* http_server_properties =
12214 session->http_server_properties();
12215 url::SchemeHostPort server("https", "www.example.org", 443);
12216 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112217 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912218 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112219 http_server_properties->SetHttp2AlternativeService(
12220 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912221
12222 // Non-alternative job should hang.
12223 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
12224 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
12225 nullptr, 0);
12226 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12227 session_deps_.socket_factory->AddSocketDataProvider(
12228 &hanging_alternate_protocol_socket);
12229
bnc032658ba2016-09-26 18:17:1512230 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912231
12232 HttpRequestInfo request;
12233 request.method = "GET";
12234 request.url = GURL("https://www.example.org/");
12235 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012236 request.traffic_annotation =
12237 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912238
12239 SpdySerializedFrame req(
12240 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12241
12242 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12243
12244 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12245 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12246 MockRead spdy_reads[] = {
12247 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12248 };
12249
12250 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12251 arraysize(spdy_writes));
12252 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12253
12254 TestCompletionCallback callback;
12255
12256 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12257
tfarina42834112016-09-22 13:38:2012258 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912259 EXPECT_THAT(callback.GetResult(rv), IsOk());
12260
12261 const HttpResponseInfo* response = trans.GetResponseInfo();
12262 ASSERT_TRUE(response);
12263 ASSERT_TRUE(response->headers);
12264 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12265 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212266 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912267
12268 std::string response_data;
12269 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12270 EXPECT_EQ("hello!", response_data);
12271
12272 // Origin host bypasses proxy, no resolution should have happened.
12273 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12274}
12275
bncd16676a2016-07-20 16:23:0112276TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112277 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212278 proxy_config.set_auto_detect(true);
12279 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112280
sammc5dd160c2015-04-02 02:43:1312281 CapturingProxyResolver capturing_proxy_resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5912282 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1912283 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
12284 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5812285 &capturing_proxy_resolver),
12286 nullptr);
vishal.b62985ca92015-04-17 08:45:5112287 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712288 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112289
12290 HttpRequestInfo request;
12291 request.method = "GET";
bncb26024382016-06-29 02:39:4512292 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012293 request.traffic_annotation =
12294 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112295
12296 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212297 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312298 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212299 MockRead("\r\n"),
12300 MockRead("hello world"),
12301 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12302 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112303 };
12304
12305 StaticSocketDataProvider first_transaction(
12306 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712307 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512308 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612309 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512310 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112311
bnc032658ba2016-09-26 18:17:1512312 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112313
bncdf80d44fd2016-07-15 20:27:4112314 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512315 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112316 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312317 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512318 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12319 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312320 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112321 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112322 };
12323
[email protected]d911f1b2010-05-05 22:39:4212324 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12325
bnc42331402016-07-25 13:36:1512326 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112327 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112328 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112329 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12330 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112331 };
12332
rch8e6c6c42015-05-01 14:05:1312333 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12334 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712335 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112336
[email protected]d973e99a2012-02-17 21:02:3612337 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512338 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12339 NULL, 0, NULL, 0);
12340 hanging_non_alternate_protocol_socket.set_connect_data(
12341 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712342 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512343 &hanging_non_alternate_protocol_socket);
12344
[email protected]49639fa2011-12-20 23:22:4112345 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112346
danakj1fd259a02016-04-16 03:17:0912347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812348 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912349 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112350
tfarina42834112016-09-22 13:38:2012351 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112352 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12353 EXPECT_THAT(callback.WaitForResult(), IsOk());
12354
12355 const HttpResponseInfo* response = trans->GetResponseInfo();
12356 ASSERT_TRUE(response);
12357 ASSERT_TRUE(response->headers);
12358 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12359 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212360 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112361
12362 std::string response_data;
12363 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12364 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112365
bnc87dcefc2017-05-25 12:47:5812366 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912367 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112368
tfarina42834112016-09-22 13:38:2012369 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12371 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112372
mmenkea2dcd3bf2016-08-16 21:49:4112373 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212374 ASSERT_TRUE(response);
12375 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212376 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312377 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212378 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112379
robpercival214763f2016-07-01 23:27:0112380 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112381 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512382 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12383 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312384 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312385 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312386 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112387
[email protected]029c83b62013-01-24 05:28:2012388 LoadTimingInfo load_timing_info;
12389 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12390 TestLoadTimingNotReusedWithPac(load_timing_info,
12391 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112392}
[email protected]631f1322010-04-30 17:59:1112393
bncd16676a2016-07-20 16:23:0112394TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812395 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412396 HttpRequestInfo request;
12397 request.method = "GET";
bncb26024382016-06-29 02:39:4512398 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012399 request.traffic_annotation =
12400 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412401
12402 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212403 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312404 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212405 MockRead("\r\n"),
12406 MockRead("hello world"),
12407 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412408 };
12409
12410 StaticSocketDataProvider first_transaction(
12411 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712412 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512413 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612414 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412416
bnc032658ba2016-09-26 18:17:1512417 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412418
bncdf80d44fd2016-07-15 20:27:4112419 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512420 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112421 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412422
bnc42331402016-07-25 13:36:1512423 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112424 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412425 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112426 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412427 };
12428
rch8e6c6c42015-05-01 14:05:1312429 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12430 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712431 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412432
[email protected]83039bb2011-12-09 18:43:5512433 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412434
danakj1fd259a02016-04-16 03:17:0912435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412436
bnc87dcefc2017-05-25 12:47:5812437 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912438 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412439
tfarina42834112016-09-22 13:38:2012440 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12442 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412443
12444 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212445 ASSERT_TRUE(response);
12446 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412447 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12448
12449 std::string response_data;
robpercival214763f2016-07-01 23:27:0112450 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412451 EXPECT_EQ("hello world", response_data);
12452
12453 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512454 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012455 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412456 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712457 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212458 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812459
bnc87dcefc2017-05-25 12:47:5812460 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912461 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412462
tfarina42834112016-09-22 13:38:2012463 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12465 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412466
12467 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212468 ASSERT_TRUE(response);
12469 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212470 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312471 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212472 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412473
robpercival214763f2016-07-01 23:27:0112474 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412475 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212476}
12477
[email protected]044de0642010-06-17 10:42:1512478// GenerateAuthToken is a mighty big test.
12479// It tests all permutation of GenerateAuthToken behavior:
12480// - Synchronous and Asynchronous completion.
12481// - OK or error on completion.
12482// - Direct connection, non-authenticating proxy, and authenticating proxy.
12483// - HTTP or HTTPS backend (to include proxy tunneling).
12484// - Non-authenticating and authenticating backend.
12485//
[email protected]fe3b7dc2012-02-03 19:52:0912486// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512487// problems generating an auth token for an authenticating proxy, we don't
12488// need to test all permutations of the backend server).
12489//
12490// The test proceeds by going over each of the configuration cases, and
12491// potentially running up to three rounds in each of the tests. The TestConfig
12492// specifies both the configuration for the test as well as the expectations
12493// for the results.
bncd16676a2016-07-20 16:23:0112494TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012495 static const char kServer[] = "http://www.example.com";
12496 static const char kSecureServer[] = "https://www.example.com";
12497 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512498
12499 enum AuthTiming {
12500 AUTH_NONE,
12501 AUTH_SYNC,
12502 AUTH_ASYNC,
12503 };
12504
12505 const MockWrite kGet(
12506 "GET / HTTP/1.1\r\n"
12507 "Host: www.example.com\r\n"
12508 "Connection: keep-alive\r\n\r\n");
12509 const MockWrite kGetProxy(
12510 "GET http://www.example.com/ HTTP/1.1\r\n"
12511 "Host: www.example.com\r\n"
12512 "Proxy-Connection: keep-alive\r\n\r\n");
12513 const MockWrite kGetAuth(
12514 "GET / HTTP/1.1\r\n"
12515 "Host: www.example.com\r\n"
12516 "Connection: keep-alive\r\n"
12517 "Authorization: auth_token\r\n\r\n");
12518 const MockWrite kGetProxyAuth(
12519 "GET http://www.example.com/ HTTP/1.1\r\n"
12520 "Host: www.example.com\r\n"
12521 "Proxy-Connection: keep-alive\r\n"
12522 "Proxy-Authorization: auth_token\r\n\r\n");
12523 const MockWrite kGetAuthThroughProxy(
12524 "GET http://www.example.com/ HTTP/1.1\r\n"
12525 "Host: www.example.com\r\n"
12526 "Proxy-Connection: keep-alive\r\n"
12527 "Authorization: auth_token\r\n\r\n");
12528 const MockWrite kGetAuthWithProxyAuth(
12529 "GET http://www.example.com/ HTTP/1.1\r\n"
12530 "Host: www.example.com\r\n"
12531 "Proxy-Connection: keep-alive\r\n"
12532 "Proxy-Authorization: auth_token\r\n"
12533 "Authorization: auth_token\r\n\r\n");
12534 const MockWrite kConnect(
12535 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712536 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512537 "Proxy-Connection: keep-alive\r\n\r\n");
12538 const MockWrite kConnectProxyAuth(
12539 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712540 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512541 "Proxy-Connection: keep-alive\r\n"
12542 "Proxy-Authorization: auth_token\r\n\r\n");
12543
12544 const MockRead kSuccess(
12545 "HTTP/1.1 200 OK\r\n"
12546 "Content-Type: text/html; charset=iso-8859-1\r\n"
12547 "Content-Length: 3\r\n\r\n"
12548 "Yes");
12549 const MockRead kFailure(
12550 "Should not be called.");
12551 const MockRead kServerChallenge(
12552 "HTTP/1.1 401 Unauthorized\r\n"
12553 "WWW-Authenticate: Mock realm=server\r\n"
12554 "Content-Type: text/html; charset=iso-8859-1\r\n"
12555 "Content-Length: 14\r\n\r\n"
12556 "Unauthorized\r\n");
12557 const MockRead kProxyChallenge(
12558 "HTTP/1.1 407 Unauthorized\r\n"
12559 "Proxy-Authenticate: Mock realm=proxy\r\n"
12560 "Proxy-Connection: close\r\n"
12561 "Content-Type: text/html; charset=iso-8859-1\r\n"
12562 "Content-Length: 14\r\n\r\n"
12563 "Unauthorized\r\n");
12564 const MockRead kProxyConnected(
12565 "HTTP/1.1 200 Connection Established\r\n\r\n");
12566
12567 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12568 // no constructors, but the C++ compiler on Windows warns about
12569 // unspecified data in compound literals. So, moved to using constructors,
12570 // and TestRound's created with the default constructor should not be used.
12571 struct TestRound {
12572 TestRound()
12573 : expected_rv(ERR_UNEXPECTED),
12574 extra_write(NULL),
12575 extra_read(NULL) {
12576 }
12577 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12578 int expected_rv_arg)
12579 : write(write_arg),
12580 read(read_arg),
12581 expected_rv(expected_rv_arg),
12582 extra_write(NULL),
12583 extra_read(NULL) {
12584 }
12585 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12586 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112587 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512588 : write(write_arg),
12589 read(read_arg),
12590 expected_rv(expected_rv_arg),
12591 extra_write(extra_write_arg),
12592 extra_read(extra_read_arg) {
12593 }
12594 MockWrite write;
12595 MockRead read;
12596 int expected_rv;
12597 const MockWrite* extra_write;
12598 const MockRead* extra_read;
12599 };
12600
12601 static const int kNoSSL = 500;
12602
12603 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112604 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112605 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512606 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112607 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112608 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512609 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112610 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512611 int num_auth_rounds;
12612 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612613 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512614 } test_configs[] = {
asankac93076192016-10-03 15:46:0212615 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112616 {__LINE__,
12617 nullptr,
asankac93076192016-10-03 15:46:0212618 AUTH_NONE,
12619 OK,
12620 kServer,
12621 AUTH_NONE,
12622 OK,
12623 1,
12624 kNoSSL,
12625 {TestRound(kGet, kSuccess, OK)}},
12626 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112627 {__LINE__,
12628 nullptr,
asankac93076192016-10-03 15:46:0212629 AUTH_NONE,
12630 OK,
12631 kServer,
12632 AUTH_SYNC,
12633 OK,
12634 2,
12635 kNoSSL,
12636 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512637 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112638 {__LINE__,
12639 nullptr,
asankac93076192016-10-03 15:46:0212640 AUTH_NONE,
12641 OK,
12642 kServer,
12643 AUTH_SYNC,
12644 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612645 3,
12646 kNoSSL,
12647 {TestRound(kGet, kServerChallenge, OK),
12648 TestRound(kGet, kServerChallenge, OK),
12649 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112650 {__LINE__,
12651 nullptr,
asankae2257db2016-10-11 22:03:1612652 AUTH_NONE,
12653 OK,
12654 kServer,
12655 AUTH_SYNC,
12656 ERR_UNSUPPORTED_AUTH_SCHEME,
12657 2,
12658 kNoSSL,
12659 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112660 {__LINE__,
12661 nullptr,
asankae2257db2016-10-11 22:03:1612662 AUTH_NONE,
12663 OK,
12664 kServer,
12665 AUTH_SYNC,
12666 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12667 2,
12668 kNoSSL,
12669 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112670 {__LINE__,
12671 kProxy,
asankae2257db2016-10-11 22:03:1612672 AUTH_SYNC,
12673 ERR_FAILED,
12674 kServer,
12675 AUTH_NONE,
12676 OK,
12677 2,
12678 kNoSSL,
12679 {TestRound(kGetProxy, kProxyChallenge, OK),
12680 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112681 {__LINE__,
12682 kProxy,
asankae2257db2016-10-11 22:03:1612683 AUTH_ASYNC,
12684 ERR_FAILED,
12685 kServer,
12686 AUTH_NONE,
12687 OK,
12688 2,
12689 kNoSSL,
12690 {TestRound(kGetProxy, kProxyChallenge, OK),
12691 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112692 {__LINE__,
12693 nullptr,
asankae2257db2016-10-11 22:03:1612694 AUTH_NONE,
12695 OK,
12696 kServer,
12697 AUTH_SYNC,
12698 ERR_FAILED,
asankac93076192016-10-03 15:46:0212699 2,
12700 kNoSSL,
12701 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612702 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112703 {__LINE__,
12704 nullptr,
asankae2257db2016-10-11 22:03:1612705 AUTH_NONE,
12706 OK,
12707 kServer,
12708 AUTH_ASYNC,
12709 ERR_FAILED,
12710 2,
12711 kNoSSL,
12712 {TestRound(kGet, kServerChallenge, OK),
12713 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112714 {__LINE__,
12715 nullptr,
asankac93076192016-10-03 15:46:0212716 AUTH_NONE,
12717 OK,
12718 kServer,
12719 AUTH_ASYNC,
12720 OK,
12721 2,
12722 kNoSSL,
12723 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512724 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112725 {__LINE__,
12726 nullptr,
asankac93076192016-10-03 15:46:0212727 AUTH_NONE,
12728 OK,
12729 kServer,
12730 AUTH_ASYNC,
12731 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612732 3,
asankac93076192016-10-03 15:46:0212733 kNoSSL,
12734 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612735 // The second round uses a HttpAuthHandlerMock that always succeeds.
12736 TestRound(kGet, kServerChallenge, OK),
12737 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212738 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112739 {__LINE__,
12740 kProxy,
asankac93076192016-10-03 15:46:0212741 AUTH_NONE,
12742 OK,
12743 kServer,
12744 AUTH_NONE,
12745 OK,
12746 1,
12747 kNoSSL,
12748 {TestRound(kGetProxy, kSuccess, OK)}},
12749 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112750 {__LINE__,
12751 kProxy,
asankac93076192016-10-03 15:46:0212752 AUTH_NONE,
12753 OK,
12754 kServer,
12755 AUTH_SYNC,
12756 OK,
12757 2,
12758 kNoSSL,
12759 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512760 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112761 {__LINE__,
12762 kProxy,
asankac93076192016-10-03 15:46:0212763 AUTH_NONE,
12764 OK,
12765 kServer,
12766 AUTH_SYNC,
12767 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612768 3,
asankac93076192016-10-03 15:46:0212769 kNoSSL,
12770 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612771 TestRound(kGetProxy, kServerChallenge, OK),
12772 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112773 {__LINE__,
12774 kProxy,
asankac93076192016-10-03 15:46:0212775 AUTH_NONE,
12776 OK,
12777 kServer,
12778 AUTH_ASYNC,
12779 OK,
12780 2,
12781 kNoSSL,
12782 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512783 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112784 {__LINE__,
12785 kProxy,
asankac93076192016-10-03 15:46:0212786 AUTH_NONE,
12787 OK,
12788 kServer,
12789 AUTH_ASYNC,
12790 ERR_INVALID_AUTH_CREDENTIALS,
12791 2,
12792 kNoSSL,
12793 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612794 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212795 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112796 {__LINE__,
12797 kProxy,
asankac93076192016-10-03 15:46:0212798 AUTH_SYNC,
12799 OK,
12800 kServer,
12801 AUTH_NONE,
12802 OK,
12803 2,
12804 kNoSSL,
12805 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512806 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112807 {__LINE__,
12808 kProxy,
asankac93076192016-10-03 15:46:0212809 AUTH_SYNC,
12810 ERR_INVALID_AUTH_CREDENTIALS,
12811 kServer,
12812 AUTH_NONE,
12813 OK,
12814 2,
12815 kNoSSL,
12816 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612817 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112818 {__LINE__,
12819 kProxy,
asankac93076192016-10-03 15:46:0212820 AUTH_ASYNC,
12821 OK,
12822 kServer,
12823 AUTH_NONE,
12824 OK,
12825 2,
12826 kNoSSL,
12827 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512828 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112829 {__LINE__,
12830 kProxy,
asankac93076192016-10-03 15:46:0212831 AUTH_ASYNC,
12832 ERR_INVALID_AUTH_CREDENTIALS,
12833 kServer,
12834 AUTH_NONE,
12835 OK,
12836 2,
12837 kNoSSL,
12838 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612839 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112840 {__LINE__,
12841 kProxy,
12842 AUTH_ASYNC,
12843 ERR_INVALID_AUTH_CREDENTIALS,
12844 kServer,
12845 AUTH_NONE,
12846 OK,
12847 3,
12848 kNoSSL,
12849 {TestRound(kGetProxy, kProxyChallenge, OK),
12850 TestRound(kGetProxy, kProxyChallenge, OK),
12851 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212852 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112853 {__LINE__,
12854 kProxy,
asankac93076192016-10-03 15:46:0212855 AUTH_SYNC,
12856 OK,
12857 kServer,
12858 AUTH_SYNC,
12859 OK,
12860 3,
12861 kNoSSL,
12862 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512863 TestRound(kGetProxyAuth, kServerChallenge, OK),
12864 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112865 {__LINE__,
12866 kProxy,
asankac93076192016-10-03 15:46:0212867 AUTH_SYNC,
12868 OK,
12869 kServer,
12870 AUTH_SYNC,
12871 ERR_INVALID_AUTH_CREDENTIALS,
12872 3,
12873 kNoSSL,
12874 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512875 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612876 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112877 {__LINE__,
12878 kProxy,
asankac93076192016-10-03 15:46:0212879 AUTH_ASYNC,
12880 OK,
12881 kServer,
12882 AUTH_SYNC,
12883 OK,
12884 3,
12885 kNoSSL,
12886 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512887 TestRound(kGetProxyAuth, kServerChallenge, OK),
12888 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112889 {__LINE__,
12890 kProxy,
asankac93076192016-10-03 15:46:0212891 AUTH_ASYNC,
12892 OK,
12893 kServer,
12894 AUTH_SYNC,
12895 ERR_INVALID_AUTH_CREDENTIALS,
12896 3,
12897 kNoSSL,
12898 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512899 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612900 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112901 {__LINE__,
12902 kProxy,
asankac93076192016-10-03 15:46:0212903 AUTH_SYNC,
12904 OK,
12905 kServer,
12906 AUTH_ASYNC,
12907 OK,
12908 3,
12909 kNoSSL,
12910 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512911 TestRound(kGetProxyAuth, kServerChallenge, OK),
12912 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112913 {__LINE__,
12914 kProxy,
12915 AUTH_SYNC,
12916 ERR_INVALID_AUTH_CREDENTIALS,
12917 kServer,
12918 AUTH_ASYNC,
12919 OK,
12920 4,
12921 kNoSSL,
12922 {TestRound(kGetProxy, kProxyChallenge, OK),
12923 TestRound(kGetProxy, kProxyChallenge, OK),
12924 TestRound(kGetProxyAuth, kServerChallenge, OK),
12925 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12926 {__LINE__,
12927 kProxy,
asankac93076192016-10-03 15:46:0212928 AUTH_SYNC,
12929 OK,
12930 kServer,
12931 AUTH_ASYNC,
12932 ERR_INVALID_AUTH_CREDENTIALS,
12933 3,
12934 kNoSSL,
12935 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512936 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612937 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112938 {__LINE__,
12939 kProxy,
asankac93076192016-10-03 15:46:0212940 AUTH_ASYNC,
12941 OK,
12942 kServer,
12943 AUTH_ASYNC,
12944 OK,
12945 3,
12946 kNoSSL,
12947 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512948 TestRound(kGetProxyAuth, kServerChallenge, OK),
12949 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112950 {__LINE__,
12951 kProxy,
asankac93076192016-10-03 15:46:0212952 AUTH_ASYNC,
12953 OK,
12954 kServer,
12955 AUTH_ASYNC,
12956 ERR_INVALID_AUTH_CREDENTIALS,
12957 3,
12958 kNoSSL,
12959 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512960 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612961 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112962 {__LINE__,
12963 kProxy,
12964 AUTH_ASYNC,
12965 ERR_INVALID_AUTH_CREDENTIALS,
12966 kServer,
12967 AUTH_ASYNC,
12968 ERR_INVALID_AUTH_CREDENTIALS,
12969 4,
12970 kNoSSL,
12971 {TestRound(kGetProxy, kProxyChallenge, OK),
12972 TestRound(kGetProxy, kProxyChallenge, OK),
12973 TestRound(kGetProxyAuth, kServerChallenge, OK),
12974 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212975 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112976 {__LINE__,
12977 nullptr,
asankac93076192016-10-03 15:46:0212978 AUTH_NONE,
12979 OK,
12980 kSecureServer,
12981 AUTH_NONE,
12982 OK,
12983 1,
12984 0,
12985 {TestRound(kGet, kSuccess, OK)}},
12986 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112987 {__LINE__,
12988 nullptr,
asankac93076192016-10-03 15:46:0212989 AUTH_NONE,
12990 OK,
12991 kSecureServer,
12992 AUTH_SYNC,
12993 OK,
12994 2,
12995 0,
12996 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512997 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112998 {__LINE__,
12999 nullptr,
asankac93076192016-10-03 15:46:0213000 AUTH_NONE,
13001 OK,
13002 kSecureServer,
13003 AUTH_SYNC,
13004 ERR_INVALID_AUTH_CREDENTIALS,
13005 2,
13006 0,
asankae2257db2016-10-11 22:03:1613007 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113008 {__LINE__,
13009 nullptr,
asankac93076192016-10-03 15:46:0213010 AUTH_NONE,
13011 OK,
13012 kSecureServer,
13013 AUTH_ASYNC,
13014 OK,
13015 2,
13016 0,
13017 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513018 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113019 {__LINE__,
13020 nullptr,
asankac93076192016-10-03 15:46:0213021 AUTH_NONE,
13022 OK,
13023 kSecureServer,
13024 AUTH_ASYNC,
13025 ERR_INVALID_AUTH_CREDENTIALS,
13026 2,
13027 0,
asankae2257db2016-10-11 22:03:1613028 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213029 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113030 {__LINE__,
13031 kProxy,
asankac93076192016-10-03 15:46:0213032 AUTH_NONE,
13033 OK,
13034 kSecureServer,
13035 AUTH_NONE,
13036 OK,
13037 1,
13038 0,
13039 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13040 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113041 {__LINE__,
13042 kProxy,
asankac93076192016-10-03 15:46:0213043 AUTH_NONE,
13044 OK,
13045 kSecureServer,
13046 AUTH_SYNC,
13047 OK,
13048 2,
13049 0,
13050 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513051 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113052 {__LINE__,
13053 kProxy,
asankac93076192016-10-03 15:46:0213054 AUTH_NONE,
13055 OK,
13056 kSecureServer,
13057 AUTH_SYNC,
13058 ERR_INVALID_AUTH_CREDENTIALS,
13059 2,
13060 0,
13061 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613062 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113063 {__LINE__,
13064 kProxy,
asankac93076192016-10-03 15:46:0213065 AUTH_NONE,
13066 OK,
13067 kSecureServer,
13068 AUTH_ASYNC,
13069 OK,
13070 2,
13071 0,
13072 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513073 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113074 {__LINE__,
13075 kProxy,
asankac93076192016-10-03 15:46:0213076 AUTH_NONE,
13077 OK,
13078 kSecureServer,
13079 AUTH_ASYNC,
13080 ERR_INVALID_AUTH_CREDENTIALS,
13081 2,
13082 0,
13083 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613084 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213085 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113086 {__LINE__,
13087 kProxy,
asankac93076192016-10-03 15:46:0213088 AUTH_SYNC,
13089 OK,
13090 kSecureServer,
13091 AUTH_NONE,
13092 OK,
13093 2,
13094 1,
13095 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513096 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113097 {__LINE__,
13098 kProxy,
asankac93076192016-10-03 15:46:0213099 AUTH_SYNC,
13100 ERR_INVALID_AUTH_CREDENTIALS,
13101 kSecureServer,
13102 AUTH_NONE,
13103 OK,
13104 2,
13105 kNoSSL,
13106 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613107 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113108 {__LINE__,
13109 kProxy,
asankae2257db2016-10-11 22:03:1613110 AUTH_SYNC,
13111 ERR_UNSUPPORTED_AUTH_SCHEME,
13112 kSecureServer,
13113 AUTH_NONE,
13114 OK,
13115 2,
13116 kNoSSL,
13117 {TestRound(kConnect, kProxyChallenge, OK),
13118 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113119 {__LINE__,
13120 kProxy,
asankae2257db2016-10-11 22:03:1613121 AUTH_SYNC,
13122 ERR_UNEXPECTED,
13123 kSecureServer,
13124 AUTH_NONE,
13125 OK,
13126 2,
13127 kNoSSL,
13128 {TestRound(kConnect, kProxyChallenge, OK),
13129 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113130 {__LINE__,
13131 kProxy,
asankac93076192016-10-03 15:46:0213132 AUTH_ASYNC,
13133 OK,
13134 kSecureServer,
13135 AUTH_NONE,
13136 OK,
13137 2,
13138 1,
13139 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513140 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113141 {__LINE__,
13142 kProxy,
asankac93076192016-10-03 15:46:0213143 AUTH_ASYNC,
13144 ERR_INVALID_AUTH_CREDENTIALS,
13145 kSecureServer,
13146 AUTH_NONE,
13147 OK,
13148 2,
13149 kNoSSL,
13150 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613151 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213152 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113153 {__LINE__,
13154 kProxy,
asankac93076192016-10-03 15:46:0213155 AUTH_SYNC,
13156 OK,
13157 kSecureServer,
13158 AUTH_SYNC,
13159 OK,
13160 3,
13161 1,
13162 {TestRound(kConnect, kProxyChallenge, OK),
13163 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13164 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513165 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113166 {__LINE__,
13167 kProxy,
asankac93076192016-10-03 15:46:0213168 AUTH_SYNC,
13169 OK,
13170 kSecureServer,
13171 AUTH_SYNC,
13172 ERR_INVALID_AUTH_CREDENTIALS,
13173 3,
13174 1,
13175 {TestRound(kConnect, kProxyChallenge, OK),
13176 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13177 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613178 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113179 {__LINE__,
13180 kProxy,
asankac93076192016-10-03 15:46:0213181 AUTH_ASYNC,
13182 OK,
13183 kSecureServer,
13184 AUTH_SYNC,
13185 OK,
13186 3,
13187 1,
13188 {TestRound(kConnect, kProxyChallenge, OK),
13189 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13190 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513191 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113192 {__LINE__,
13193 kProxy,
asankac93076192016-10-03 15:46:0213194 AUTH_ASYNC,
13195 OK,
13196 kSecureServer,
13197 AUTH_SYNC,
13198 ERR_INVALID_AUTH_CREDENTIALS,
13199 3,
13200 1,
13201 {TestRound(kConnect, kProxyChallenge, OK),
13202 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13203 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613204 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113205 {__LINE__,
13206 kProxy,
asankac93076192016-10-03 15:46:0213207 AUTH_SYNC,
13208 OK,
13209 kSecureServer,
13210 AUTH_ASYNC,
13211 OK,
13212 3,
13213 1,
13214 {TestRound(kConnect, kProxyChallenge, OK),
13215 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13216 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513217 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113218 {__LINE__,
13219 kProxy,
asankac93076192016-10-03 15:46:0213220 AUTH_SYNC,
13221 OK,
13222 kSecureServer,
13223 AUTH_ASYNC,
13224 ERR_INVALID_AUTH_CREDENTIALS,
13225 3,
13226 1,
13227 {TestRound(kConnect, kProxyChallenge, OK),
13228 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13229 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613230 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113231 {__LINE__,
13232 kProxy,
asankac93076192016-10-03 15:46:0213233 AUTH_ASYNC,
13234 OK,
13235 kSecureServer,
13236 AUTH_ASYNC,
13237 OK,
13238 3,
13239 1,
13240 {TestRound(kConnect, kProxyChallenge, OK),
13241 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13242 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513243 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113244 {__LINE__,
13245 kProxy,
asankac93076192016-10-03 15:46:0213246 AUTH_ASYNC,
13247 OK,
13248 kSecureServer,
13249 AUTH_ASYNC,
13250 ERR_INVALID_AUTH_CREDENTIALS,
13251 3,
13252 1,
13253 {TestRound(kConnect, kProxyChallenge, OK),
13254 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13255 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613256 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113257 {__LINE__,
13258 kProxy,
13259 AUTH_ASYNC,
13260 ERR_INVALID_AUTH_CREDENTIALS,
13261 kSecureServer,
13262 AUTH_ASYNC,
13263 ERR_INVALID_AUTH_CREDENTIALS,
13264 4,
13265 2,
13266 {TestRound(kConnect, kProxyChallenge, OK),
13267 TestRound(kConnect, kProxyChallenge, OK),
13268 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13269 &kServerChallenge),
13270 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513271 };
13272
asanka463ca4262016-11-16 02:34:3113273 for (const auto& test_config : test_configs) {
13274 SCOPED_TRACE(::testing::Message() << "Test config at "
13275 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813276 HttpAuthHandlerMock::Factory* auth_factory(
13277 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713278 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913279 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613280
13281 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513282 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113283 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813284 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13285 std::string auth_challenge = "Mock realm=proxy";
13286 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413287 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13288 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813289 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013290 empty_ssl_info, origin,
13291 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813292 auth_handler->SetGenerateExpectation(
13293 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113294 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813295 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13296 }
[email protected]044de0642010-06-17 10:42:1513297 }
13298 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013299 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513300 std::string auth_challenge = "Mock realm=server";
13301 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413302 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13303 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513304 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013305 empty_ssl_info, origin,
13306 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513307 auth_handler->SetGenerateExpectation(
13308 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113309 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813310 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613311
13312 // The second handler always succeeds. It should only be used where there
13313 // are multiple auth sessions for server auth in the same network
13314 // transaction using the same auth scheme.
13315 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913316 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613317 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13318 empty_ssl_info, origin,
13319 NetLogWithSource());
13320 second_handler->SetGenerateExpectation(true, OK);
13321 auth_factory->AddMockHandler(second_handler.release(),
13322 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513323 }
13324 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913325 session_deps_.proxy_resolution_service =
13326 ProxyResolutionService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1513327 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913328 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513329 }
13330
13331 HttpRequestInfo request;
13332 request.method = "GET";
13333 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1013334 request.traffic_annotation =
13335 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513336
danakj1fd259a02016-04-16 03:17:0913337 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513338
rchcb68dc62015-05-21 04:45:3613339 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13340
13341 std::vector<std::vector<MockRead>> mock_reads(1);
13342 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513343 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213344 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513345 const TestRound& read_write_round = test_config.rounds[round];
13346
13347 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613348 mock_reads.back().push_back(read_write_round.read);
13349 mock_writes.back().push_back(read_write_round.write);
13350
13351 // kProxyChallenge uses Proxy-Connection: close which means that the
13352 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413353 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613354 mock_reads.push_back(std::vector<MockRead>());
13355 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513356 }
13357
rchcb68dc62015-05-21 04:45:3613358 if (read_write_round.extra_read) {
13359 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513360 }
rchcb68dc62015-05-21 04:45:3613361 if (read_write_round.extra_write) {
13362 mock_writes.back().push_back(*read_write_round.extra_write);
13363 }
[email protected]044de0642010-06-17 10:42:1513364
13365 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513366 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713367 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513368 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613369 }
[email protected]044de0642010-06-17 10:42:1513370
danakj1fd259a02016-04-16 03:17:0913371 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613372 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913373 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413374 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813375 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613376 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213377 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613378 }
13379
mmenkecc2298e2015-12-07 18:20:1813380 // Transaction must be created after DataProviders, so it's destroyed before
13381 // they are as well.
13382 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13383
rchcb68dc62015-05-21 04:45:3613384 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213385 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613386 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513387 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113388 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513389 int rv;
13390 if (round == 0) {
tfarina42834112016-09-22 13:38:2013391 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513392 } else {
[email protected]49639fa2011-12-20 23:22:4113393 rv = trans.RestartWithAuth(
13394 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513395 }
13396 if (rv == ERR_IO_PENDING)
13397 rv = callback.WaitForResult();
13398
13399 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613400 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013401 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513402 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513403 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13404 continue;
13405 }
13406 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213407 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513408 } else {
wezca1070932016-05-26 20:30:5213409 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613410 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513411 }
13412 }
[email protected]e5ae96a2010-04-14 20:12:4513413 }
13414}
13415
bncd16676a2016-07-20 16:23:0113416TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413417 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413418 HttpAuthHandlerMock::Factory* auth_factory(
13419 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713420 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913421 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713422 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13423 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413424
13425 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13426 auth_handler->set_connection_based(true);
13427 std::string auth_challenge = "Mock realm=server";
13428 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413429 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13430 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913431 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413432 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013433 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813434 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413435
[email protected]c871bce92010-07-15 21:51:1413436 int rv = OK;
13437 const HttpResponseInfo* response = NULL;
13438 HttpRequestInfo request;
13439 request.method = "GET";
13440 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1013441 request.traffic_annotation =
13442 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713443
danakj1fd259a02016-04-16 03:17:0913444 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013445
13446 // Use a TCP Socket Pool with only one connection per group. This is used
13447 // to validate that the TCP socket is not released to the pool between
13448 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213449 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813450 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013451 50, // Max sockets for pool
13452 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113453 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13454 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913455 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213456 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813457 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013458
bnc691fda62016-08-12 00:43:1613459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113460 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413461
13462 const MockWrite kGet(
13463 "GET / HTTP/1.1\r\n"
13464 "Host: www.example.com\r\n"
13465 "Connection: keep-alive\r\n\r\n");
13466 const MockWrite kGetAuth(
13467 "GET / HTTP/1.1\r\n"
13468 "Host: www.example.com\r\n"
13469 "Connection: keep-alive\r\n"
13470 "Authorization: auth_token\r\n\r\n");
13471
13472 const MockRead kServerChallenge(
13473 "HTTP/1.1 401 Unauthorized\r\n"
13474 "WWW-Authenticate: Mock realm=server\r\n"
13475 "Content-Type: text/html; charset=iso-8859-1\r\n"
13476 "Content-Length: 14\r\n\r\n"
13477 "Unauthorized\r\n");
13478 const MockRead kSuccess(
13479 "HTTP/1.1 200 OK\r\n"
13480 "Content-Type: text/html; charset=iso-8859-1\r\n"
13481 "Content-Length: 3\r\n\r\n"
13482 "Yes");
13483
13484 MockWrite writes[] = {
13485 // First round
13486 kGet,
13487 // Second round
13488 kGetAuth,
13489 // Third round
13490 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013491 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013492 kGetAuth,
13493 // Competing request
13494 kGet,
[email protected]c871bce92010-07-15 21:51:1413495 };
13496 MockRead reads[] = {
13497 // First round
13498 kServerChallenge,
13499 // Second round
13500 kServerChallenge,
13501 // Third round
[email protected]eca50e122010-09-11 14:03:3013502 kServerChallenge,
13503 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413504 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013505 // Competing response
13506 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413507 };
13508 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13509 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713510 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413511
thestig9d3bb0c2015-01-24 00:49:5113512 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013513
13514 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413515 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013516 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413517 if (rv == ERR_IO_PENDING)
13518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113519 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613520 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213521 ASSERT_TRUE(response);
13522 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813523 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113524 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13525 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413526
[email protected]7ef4cbbb2011-02-06 11:19:1013527 // In between rounds, another request comes in for the same domain.
13528 // It should not be able to grab the TCP socket that trans has already
13529 // claimed.
bnc691fda62016-08-12 00:43:1613530 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113531 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013532 rv = trans_compete.Start(&request, callback_compete.callback(),
13533 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013535 // callback_compete.WaitForResult at this point would stall forever,
13536 // since the HttpNetworkTransaction does not release the request back to
13537 // the pool until after authentication completes.
13538
13539 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413540 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613541 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413542 if (rv == ERR_IO_PENDING)
13543 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113544 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613545 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213546 ASSERT_TRUE(response);
13547 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813548 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113549 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13550 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413551
[email protected]7ef4cbbb2011-02-06 11:19:1013552 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413553 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613554 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413555 if (rv == ERR_IO_PENDING)
13556 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113557 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613558 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213559 ASSERT_TRUE(response);
13560 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813561 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113562 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13563 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013564
[email protected]7ef4cbbb2011-02-06 11:19:1013565 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013566 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613567 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013568 if (rv == ERR_IO_PENDING)
13569 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113570 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613571 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213572 ASSERT_TRUE(response);
13573 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813574 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013575
asanka463ca4262016-11-16 02:34:3113576 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13577 // auth handler should transition to a DONE state in concert with the remote
13578 // server. But that's not something we can test here with a mock handler.
13579 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13580 auth_handler->state());
13581
[email protected]7ef4cbbb2011-02-06 11:19:1013582 // Read the body since the fourth round was successful. This will also
13583 // release the socket back to the pool.
13584 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613585 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013586 if (rv == ERR_IO_PENDING)
13587 rv = callback.WaitForResult();
13588 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613589 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013590 EXPECT_EQ(0, rv);
13591 // There are still 0 idle sockets, since the trans_compete transaction
13592 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813593 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013594
13595 // The competing request can now finish. Wait for the headers and then
13596 // read the body.
13597 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113598 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613599 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013600 if (rv == ERR_IO_PENDING)
13601 rv = callback.WaitForResult();
13602 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613603 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013604 EXPECT_EQ(0, rv);
13605
13606 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813607 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413608}
13609
[email protected]65041fa2010-05-21 06:56:5313610// This tests the case that a request is issued via http instead of spdy after
13611// npn is negotiated.
bncd16676a2016-07-20 16:23:0113612TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313613 HttpRequestInfo request;
13614 request.method = "GET";
bncce36dca22015-04-21 22:11:2313615 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013616 request.traffic_annotation =
13617 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313618
13619 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313620 MockWrite(
13621 "GET / HTTP/1.1\r\n"
13622 "Host: www.example.org\r\n"
13623 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313624 };
13625
13626 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213627 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313628 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213629 MockRead("\r\n"),
13630 MockRead("hello world"),
13631 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313632 };
13633
[email protected]8ddf8322012-02-23 18:08:0613634 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613635 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313636
[email protected]bb88e1d32013-05-03 23:11:0713637 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313638
13639 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13640 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713641 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313642
[email protected]49639fa2011-12-20 23:22:4113643 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313644
danakj1fd259a02016-04-16 03:17:0913645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313647
tfarina42834112016-09-22 13:38:2013648 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313649
robpercival214763f2016-07-01 23:27:0113650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13651 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313652
bnc691fda62016-08-12 00:43:1613653 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213654 ASSERT_TRUE(response);
13655 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313656 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13657
13658 std::string response_data;
bnc691fda62016-08-12 00:43:1613659 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313660 EXPECT_EQ("hello world", response_data);
13661
13662 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213663 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313664}
[email protected]26ef6582010-06-24 02:30:4713665
bnc55ff9da2015-08-19 18:42:3513666// Simulate the SSL handshake completing with an NPN negotiation followed by an
13667// immediate server closing of the socket.
13668// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113669TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713670 HttpRequestInfo request;
13671 request.method = "GET";
bncce36dca22015-04-21 22:11:2313672 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013673 request.traffic_annotation =
13674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713675
[email protected]8ddf8322012-02-23 18:08:0613676 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613677 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713678 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713679
Bence Béky27ad0a12018-02-08 00:35:4813680 SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113681 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713682
13683 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613684 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713685 };
13686
rch8e6c6c42015-05-01 14:05:1313687 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13688 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713689 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713690
[email protected]49639fa2011-12-20 23:22:4113691 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713692
danakj1fd259a02016-04-16 03:17:0913693 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613694 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713695
tfarina42834112016-09-22 13:38:2013696 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113697 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13698 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713699}
[email protected]65d34382010-07-01 18:12:2613700
[email protected]795cbf82013-07-22 09:37:2713701// A subclass of HttpAuthHandlerMock that records the request URL when
13702// it gets it. This is needed since the auth handler may get destroyed
13703// before we get a chance to query it.
13704class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13705 public:
13706 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13707
Chris Watkins7a41d3552017-12-01 02:13:2713708 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713709
13710 protected:
dchengb03027d2014-10-21 12:00:2013711 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13712 const HttpRequestInfo* request,
13713 const CompletionCallback& callback,
13714 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713715 *url_ = request->url;
13716 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13717 credentials, request, callback, auth_token);
13718 }
13719
13720 private:
13721 GURL* url_;
13722};
13723
[email protected]8e6441ca2010-08-19 05:56:3813724// Test that if we cancel the transaction as the connection is completing, that
13725// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113726TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813727 // Setup everything about the connection to complete synchronously, so that
13728 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13729 // for is the callback from the HttpStreamRequest.
13730 // Then cancel the transaction.
13731 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613732 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813733 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613734 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13735 MockRead(SYNCHRONOUS, "hello world"),
13736 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813737 };
13738
[email protected]8e6441ca2010-08-19 05:56:3813739 HttpRequestInfo request;
13740 request.method = "GET";
bncce36dca22015-04-21 22:11:2313741 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013742 request.traffic_annotation =
13743 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813744
[email protected]bb88e1d32013-05-03 23:11:0713745 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813747 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913748 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713749
[email protected]8e6441ca2010-08-19 05:56:3813750 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13751 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713752 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813753
[email protected]49639fa2011-12-20 23:22:4113754 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813755
vishal.b62985ca92015-04-17 08:45:5113756 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113757 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813759 trans.reset(); // Cancel the transaction here.
13760
fdoray92e35a72016-06-10 15:54:5513761 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013762}
13763
[email protected]ecab6e052014-05-16 14:58:1213764// Test that if a transaction is cancelled after receiving the headers, the
13765// stream is drained properly and added back to the socket pool. The main
13766// purpose of this test is to make sure that an HttpStreamParser can be read
13767// from after the HttpNetworkTransaction and the objects it owns have been
13768// deleted.
13769// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113770TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213771 MockRead data_reads[] = {
13772 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13773 MockRead(ASYNC, "Content-Length: 2\r\n"),
13774 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13775 MockRead(ASYNC, "1"),
13776 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13777 // HttpNetworkTransaction has been deleted.
13778 MockRead(ASYNC, "2"),
13779 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13780 };
13781 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13782 session_deps_.socket_factory->AddSocketDataProvider(&data);
13783
danakj1fd259a02016-04-16 03:17:0913784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213785
13786 {
13787 HttpRequestInfo request;
13788 request.method = "GET";
bncce36dca22015-04-21 22:11:2313789 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013790 request.traffic_annotation =
13791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213792
dcheng48459ac22014-08-26 00:46:4113793 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213794 TestCompletionCallback callback;
13795
tfarina42834112016-09-22 13:38:2013796 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213798 callback.WaitForResult();
13799
13800 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213801 ASSERT_TRUE(response);
13802 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213803 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13804
13805 // The transaction and HttpRequestInfo are deleted.
13806 }
13807
13808 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513809 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213810
13811 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113812 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213813}
13814
[email protected]76a505b2010-08-25 06:23:0013815// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113816TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913817 session_deps_.proxy_resolution_service =
13818 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113819 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713820 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013822
[email protected]76a505b2010-08-25 06:23:0013823 HttpRequestInfo request;
13824 request.method = "GET";
bncce36dca22015-04-21 22:11:2313825 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013826 request.traffic_annotation =
13827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013828
13829 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313830 MockWrite(
13831 "GET http://www.example.org/ HTTP/1.1\r\n"
13832 "Host: www.example.org\r\n"
13833 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013834 };
13835
13836 MockRead data_reads1[] = {
13837 MockRead("HTTP/1.1 200 OK\r\n"),
13838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13839 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613840 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013841 };
13842
13843 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13844 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713845 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013846
[email protected]49639fa2011-12-20 23:22:4113847 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013848
bnc691fda62016-08-12 00:43:1613849 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913850 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613851 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913852 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13853 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013854
bnc691fda62016-08-12 00:43:1613855 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013857
13858 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113859 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013860
bnc691fda62016-08-12 00:43:1613861 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213862 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013863
13864 EXPECT_TRUE(response->headers->IsKeepAlive());
13865 EXPECT_EQ(200, response->headers->response_code());
13866 EXPECT_EQ(100, response->headers->GetContentLength());
13867 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713868 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13869 HostPortPair::FromString("myproxy:70")),
13870 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913871 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13872 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13873 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013874 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013875
13876 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613877 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013878 TestLoadTimingNotReusedWithPac(load_timing_info,
13879 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013880}
13881
13882// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113883TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913884 session_deps_.proxy_resolution_service =
13885 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113886 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713887 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013889
[email protected]76a505b2010-08-25 06:23:0013890 HttpRequestInfo request;
13891 request.method = "GET";
bncce36dca22015-04-21 22:11:2313892 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013893 request.traffic_annotation =
13894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013895
13896 // Since we have proxy, should try to establish tunnel.
13897 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713898 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13899 "Host: www.example.org:443\r\n"
13900 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013901
rsleevidb16bb02015-11-12 23:47:1713902 MockWrite("GET / HTTP/1.1\r\n"
13903 "Host: www.example.org\r\n"
13904 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013905 };
13906
13907 MockRead data_reads1[] = {
13908 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13909
13910 MockRead("HTTP/1.1 200 OK\r\n"),
13911 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13912 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613913 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013914 };
13915
13916 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13917 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713918 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613919 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713920 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013921
[email protected]49639fa2011-12-20 23:22:4113922 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013923
bnc691fda62016-08-12 00:43:1613924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913925 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613926 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913927 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13928 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013929
bnc691fda62016-08-12 00:43:1613930 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013932
13933 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113934 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613935 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013936 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013937 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013938 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13939 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013940 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013941 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013942 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13943 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013944
bnc691fda62016-08-12 00:43:1613945 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213946 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013947
13948 EXPECT_TRUE(response->headers->IsKeepAlive());
13949 EXPECT_EQ(200, response->headers->response_code());
13950 EXPECT_EQ(100, response->headers->GetContentLength());
13951 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13952 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713953 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13954 HostPortPair::FromString("myproxy:70")),
13955 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913956 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13957 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13958 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013959
13960 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613961 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013962 TestLoadTimingNotReusedWithPac(load_timing_info,
13963 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013964}
13965
rsleevidb16bb02015-11-12 23:47:1713966// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13967// literal host.
bncd16676a2016-07-20 16:23:0113968TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913969 session_deps_.proxy_resolution_service =
13970 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
rsleevidb16bb02015-11-12 23:47:1713971 BoundTestNetLog log;
13972 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913973 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713974
13975 HttpRequestInfo request;
13976 request.method = "GET";
13977 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1013978 request.traffic_annotation =
13979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713980
13981 // Since we have proxy, should try to establish tunnel.
13982 MockWrite data_writes1[] = {
13983 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13984 "Host: [::1]:443\r\n"
13985 "Proxy-Connection: keep-alive\r\n\r\n"),
13986
13987 MockWrite("GET / HTTP/1.1\r\n"
13988 "Host: [::1]\r\n"
13989 "Connection: keep-alive\r\n\r\n"),
13990 };
13991
13992 MockRead data_reads1[] = {
13993 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13994
13995 MockRead("HTTP/1.1 200 OK\r\n"),
13996 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13997 MockRead("Content-Length: 100\r\n\r\n"),
13998 MockRead(SYNCHRONOUS, OK),
13999 };
14000
14001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14002 data_writes1, arraysize(data_writes1));
14003 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14004 SSLSocketDataProvider ssl(ASYNC, OK);
14005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14006
14007 TestCompletionCallback callback1;
14008
bnc691fda62016-08-12 00:43:1614009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714010
bnc691fda62016-08-12 00:43:1614011 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714013
14014 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114015 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714016 TestNetLogEntry::List entries;
14017 log.GetEntries(&entries);
14018 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014019 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14020 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714021 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014022 entries, pos,
14023 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14024 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714025
bnc691fda62016-08-12 00:43:1614026 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214027 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714028
14029 EXPECT_TRUE(response->headers->IsKeepAlive());
14030 EXPECT_EQ(200, response->headers->response_code());
14031 EXPECT_EQ(100, response->headers->GetContentLength());
14032 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14033 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714034 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14035 HostPortPair::FromString("myproxy:70")),
14036 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714037
14038 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614039 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714040 TestLoadTimingNotReusedWithPac(load_timing_info,
14041 CONNECT_TIMING_HAS_SSL_TIMES);
14042}
14043
[email protected]76a505b2010-08-25 06:23:0014044// Test a basic HTTPS GET request through a proxy, but the server hangs up
14045// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114046TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Lily Houghton8c2f97d2018-01-22 05:06:5914047 session_deps_.proxy_resolution_service =
14048 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5114049 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714050 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014052
[email protected]76a505b2010-08-25 06:23:0014053 HttpRequestInfo request;
14054 request.method = "GET";
bncce36dca22015-04-21 22:11:2314055 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014056 request.traffic_annotation =
14057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014058
14059 // Since we have proxy, should try to establish tunnel.
14060 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714061 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14062 "Host: www.example.org:443\r\n"
14063 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014064
rsleevidb16bb02015-11-12 23:47:1714065 MockWrite("GET / HTTP/1.1\r\n"
14066 "Host: www.example.org\r\n"
14067 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014068 };
14069
14070 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014071 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614072 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014073 };
14074
14075 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14076 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714077 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614078 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014080
[email protected]49639fa2011-12-20 23:22:4114081 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014082
bnc691fda62016-08-12 00:43:1614083 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014084
bnc691fda62016-08-12 00:43:1614085 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014087
14088 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114089 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614090 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014091 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014092 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014093 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14094 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014095 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014096 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014097 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14098 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014099}
14100
[email protected]749eefa82010-09-13 22:14:0314101// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114102TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114103 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914104 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114105 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314106
bnc42331402016-07-25 13:36:1514107 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114108 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314109 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114110 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314111 };
14112
rch8e6c6c42015-05-01 14:05:1314113 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
14114 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714115 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314116
[email protected]8ddf8322012-02-23 18:08:0614117 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614118 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314120
danakj1fd259a02016-04-16 03:17:0914121 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314122
14123 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314124 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014125 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414126 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714127 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214128 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314129
14130 HttpRequestInfo request;
14131 request.method = "GET";
bncce36dca22015-04-21 22:11:2314132 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014133 request.traffic_annotation =
14134 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314135
14136 // This is the important line that marks this as a preconnect.
14137 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14138
bnc691fda62016-08-12 00:43:1614139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314140
[email protected]41d64e82013-07-03 22:44:2614141 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014142 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114143 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14144 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314145}
14146
[email protected]73b8dd222010-11-11 19:55:2414147// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614148// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214149void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714150 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914151 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714152 request_info.url = GURL("https://www.example.com/");
14153 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914154 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014155 request_info.traffic_annotation =
14156 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714157
[email protected]8ddf8322012-02-23 18:08:0614158 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914159 MockWrite data_writes[] = {
14160 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414161 };
ttuttle859dc7a2015-04-23 19:42:2914162 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0714163 session_deps_.socket_factory->AddSocketDataProvider(&data);
14164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414165
danakj1fd259a02016-04-16 03:17:0914166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614167 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414168
[email protected]49639fa2011-12-20 23:22:4114169 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014170 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914171 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414172 rv = callback.WaitForResult();
14173 ASSERT_EQ(error, rv);
14174}
14175
bncd16676a2016-07-20 16:23:0114176TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414177 // Just check a grab bag of cert errors.
14178 static const int kErrors[] = {
14179 ERR_CERT_COMMON_NAME_INVALID,
14180 ERR_CERT_AUTHORITY_INVALID,
14181 ERR_CERT_DATE_INVALID,
14182 };
14183 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614184 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14185 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414186 }
14187}
14188
[email protected]bd0b6772011-01-11 19:59:3014189// Ensure that a client certificate is removed from the SSL client auth
14190// cache when:
14191// 1) No proxy is involved.
14192// 2) TLS False Start is disabled.
14193// 3) The initial TLS handshake requests a client certificate.
14194// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114195TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914196 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714197 request_info.url = GURL("https://www.example.com/");
14198 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914199 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014200 request_info.traffic_annotation =
14201 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714202
[email protected]bd0b6772011-01-11 19:59:3014203 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114204 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014205
14206 // [ssl_]data1 contains the data for the first SSL handshake. When a
14207 // CertificateRequest is received for the first time, the handshake will
14208 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914209 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014210 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714211 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914212 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714213 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014214
14215 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14216 // False Start is not being used, the result of the SSL handshake will be
14217 // returned as part of the SSLClientSocket::Connect() call. This test
14218 // matches the result of a server sending a handshake_failure alert,
14219 // rather than a Finished message, because it requires a client
14220 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914221 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014222 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914224 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714225 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014226
14227 // [ssl_]data3 contains the data for the third SSL handshake. When a
14228 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214229 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14230 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014231 // of the HttpNetworkTransaction. Because this test failure is due to
14232 // requiring a client certificate, this fallback handshake should also
14233 // fail.
ttuttle859dc7a2015-04-23 19:42:2914234 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014235 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914237 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714238 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014239
[email protected]80c75f682012-05-26 16:22:1714240 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14241 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214242 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14243 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714244 // of the HttpNetworkTransaction. Because this test failure is due to
14245 // requiring a client certificate, this fallback handshake should also
14246 // fail.
ttuttle859dc7a2015-04-23 19:42:2914247 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714248 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914250 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714251 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714252
danakj1fd259a02016-04-16 03:17:0914253 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014255
[email protected]bd0b6772011-01-11 19:59:3014256 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114257 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014258 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114259 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014260
14261 // Complete the SSL handshake, which should abort due to requiring a
14262 // client certificate.
14263 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114264 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014265
14266 // Indicate that no certificate should be supplied. From the perspective
14267 // of SSLClientCertCache, NULL is just as meaningful as a real
14268 // certificate, so this is the same as supply a
14269 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614270 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114271 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014272
14273 // Ensure the certificate was added to the client auth cache before
14274 // allowing the connection to continue restarting.
14275 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414276 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114277 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414278 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214279 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014280
14281 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714282 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14283 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014284 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114285 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014286
14287 // Ensure that the client certificate is removed from the cache on a
14288 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114289 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414290 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014291}
14292
14293// Ensure that a client certificate is removed from the SSL client auth
14294// cache when:
14295// 1) No proxy is involved.
14296// 2) TLS False Start is enabled.
14297// 3) The initial TLS handshake requests a client certificate.
14298// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114299TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914300 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714301 request_info.url = GURL("https://www.example.com/");
14302 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914303 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014304 request_info.traffic_annotation =
14305 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714306
[email protected]bd0b6772011-01-11 19:59:3014307 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114308 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014309
14310 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14311 // return successfully after reading up to the peer's Certificate message.
14312 // This is to allow the caller to call SSLClientSocket::Write(), which can
14313 // enqueue application data to be sent in the same packet as the
14314 // ChangeCipherSpec and Finished messages.
14315 // The actual handshake will be finished when SSLClientSocket::Read() is
14316 // called, which expects to process the peer's ChangeCipherSpec and
14317 // Finished messages. If there was an error negotiating with the peer,
14318 // such as due to the peer requiring a client certificate when none was
14319 // supplied, the alert sent by the peer won't be processed until Read() is
14320 // called.
14321
14322 // Like the non-False Start case, when a client certificate is requested by
14323 // the peer, the handshake is aborted during the Connect() call.
14324 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914325 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014326 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914328 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014330
14331 // When a client certificate is supplied, Connect() will not be aborted
14332 // when the peer requests the certificate. Instead, the handshake will
14333 // artificially succeed, allowing the caller to write the HTTP request to
14334 // the socket. The handshake messages are not processed until Read() is
14335 // called, which then detects that the handshake was aborted, due to the
14336 // peer sending a handshake_failure because it requires a client
14337 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914338 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014339 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914341 MockRead data2_reads[] = {
14342 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014343 };
ttuttle859dc7a2015-04-23 19:42:2914344 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714345 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014346
14347 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714348 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14349 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914350 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014351 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914353 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714354 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014355
[email protected]80c75f682012-05-26 16:22:1714356 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14357 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914358 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714359 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914361 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714362 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714363
[email protected]7799de12013-05-30 05:52:5114364 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914365 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114366 ssl_data5.cert_request_info = cert_request.get();
14367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914368 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114369 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14370
danakj1fd259a02016-04-16 03:17:0914371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014373
[email protected]bd0b6772011-01-11 19:59:3014374 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114375 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014376 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114377 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014378
14379 // Complete the SSL handshake, which should abort due to requiring a
14380 // client certificate.
14381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114382 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014383
14384 // Indicate that no certificate should be supplied. From the perspective
14385 // of SSLClientCertCache, NULL is just as meaningful as a real
14386 // certificate, so this is the same as supply a
14387 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614388 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114389 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014390
14391 // Ensure the certificate was added to the client auth cache before
14392 // allowing the connection to continue restarting.
14393 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414394 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114395 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414396 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214397 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014398
[email protected]bd0b6772011-01-11 19:59:3014399 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714400 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14401 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114403 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014404
14405 // Ensure that the client certificate is removed from the cache on a
14406 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114407 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414408 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014409}
14410
[email protected]8c405132011-01-11 22:03:1814411// Ensure that a client certificate is removed from the SSL client auth
14412// cache when:
14413// 1) An HTTPS proxy is involved.
14414// 3) The HTTPS proxy requests a client certificate.
14415// 4) The client supplies an invalid/unacceptable certificate for the
14416// proxy.
14417// The test is repeated twice, first for connecting to an HTTPS endpoint,
14418// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114419TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Lily Houghton8c2f97d2018-01-22 05:06:5914420 session_deps_.proxy_resolution_service =
14421 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114422 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714423 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814424
14425 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114426 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814427
14428 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14429 // [ssl_]data[1-3]. Rather than represending the endpoint
14430 // (www.example.com:443), they represent failures with the HTTPS proxy
14431 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914432 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814433 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914435 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714436 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814437
ttuttle859dc7a2015-04-23 19:42:2914438 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814439 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914441 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714442 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814443
[email protected]80c75f682012-05-26 16:22:1714444 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14445#if 0
ttuttle859dc7a2015-04-23 19:42:2914446 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814447 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914449 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714450 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714451#endif
[email protected]8c405132011-01-11 22:03:1814452
ttuttle859dc7a2015-04-23 19:42:2914453 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814454 requests[0].url = GURL("https://www.example.com/");
14455 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914456 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014457 requests[0].traffic_annotation =
14458 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814459
14460 requests[1].url = GURL("http://www.example.com/");
14461 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914462 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014463 requests[1].traffic_annotation =
14464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814465
14466 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714467 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814470
14471 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114472 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014473 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114474 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814475
14476 // Complete the SSL handshake, which should abort due to requiring a
14477 // client certificate.
14478 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114479 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814480
14481 // Indicate that no certificate should be supplied. From the perspective
14482 // of SSLClientCertCache, NULL is just as meaningful as a real
14483 // certificate, so this is the same as supply a
14484 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614485 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114486 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814487
14488 // Ensure the certificate was added to the client auth cache before
14489 // allowing the connection to continue restarting.
14490 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414491 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114492 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414493 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214494 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814495 // Ensure the certificate was NOT cached for the endpoint. This only
14496 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114497 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414498 HostPortPair("www.example.com", 443), &client_cert,
14499 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814500
14501 // Restart the handshake. This will consume ssl_data2, which fails, and
14502 // then consume ssl_data3, which should also fail. The result code is
14503 // checked against what ssl_data3 should return.
14504 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114505 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814506
14507 // Now that the new handshake has failed, ensure that the client
14508 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114509 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414510 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114511 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414512 HostPortPair("www.example.com", 443), &client_cert,
14513 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814514 }
14515}
14516
bncd16676a2016-07-20 16:23:0114517TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614518 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914519 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614521
bnc032658ba2016-09-26 18:17:1514522 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614523
bncdf80d44fd2016-07-15 20:27:4114524 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914525 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814526 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114527 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714528 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614529 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114530 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614531 };
bnc42331402016-07-25 13:36:1514532 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114533 SpdySerializedFrame host1_resp_body(
14534 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514535 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114536 SpdySerializedFrame host2_resp_body(
14537 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614538 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114539 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14540 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314541 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614542 };
14543
eroman36d84e54432016-03-17 03:23:0214544 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214545 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314546 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14547 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714548 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614549
[email protected]aa22b242011-11-16 18:58:2914550 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614551 HttpRequestInfo request1;
14552 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314553 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614554 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014555 request1.traffic_annotation =
14556 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014557 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614558
tfarina42834112016-09-22 13:38:2014559 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14561 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614562
14563 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214564 ASSERT_TRUE(response);
14565 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214566 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614567
14568 std::string response_data;
robpercival214763f2016-07-01 23:27:0114569 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614570 EXPECT_EQ("hello!", response_data);
14571
bnca4d611d2016-09-22 19:55:3714572 // Preload mail.example.com into HostCache.
14573 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014574 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614575 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014576 std::unique_ptr<HostResolver::Request> request;
14577 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14578 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014579 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714581 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114582 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614583
14584 HttpRequestInfo request2;
14585 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714586 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614587 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014588 request2.traffic_annotation =
14589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014590 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614591
tfarina42834112016-09-22 13:38:2014592 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114593 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14594 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614595
14596 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214597 ASSERT_TRUE(response);
14598 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214599 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614600 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214601 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114602 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614603 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614604}
14605
bncd16676a2016-07-20 16:23:0114606TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214607 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914608 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214610
bnc032658ba2016-09-26 18:17:1514611 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214612
bncdf80d44fd2016-07-15 20:27:4114613 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914614 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814615 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114616 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714617 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214618 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114619 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214620 };
bnc42331402016-07-25 13:36:1514621 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114622 SpdySerializedFrame host1_resp_body(
14623 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514624 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114625 SpdySerializedFrame host2_resp_body(
14626 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214627 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114628 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14629 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314630 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214631 };
14632
eroman36d84e54432016-03-17 03:23:0214633 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214634 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314635 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14636 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714637 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214638
14639 TestCompletionCallback callback;
14640 HttpRequestInfo request1;
14641 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314642 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214643 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014644 request1.traffic_annotation =
14645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014646 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214647
tfarina42834112016-09-22 13:38:2014648 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14650 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214651
14652 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214653 ASSERT_TRUE(response);
14654 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214655 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214656
14657 std::string response_data;
robpercival214763f2016-07-01 23:27:0114658 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214659 EXPECT_EQ("hello!", response_data);
14660
14661 HttpRequestInfo request2;
14662 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714663 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214664 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014665 request2.traffic_annotation =
14666 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014667 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214668
tfarina42834112016-09-22 13:38:2014669 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14671 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214672
14673 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214674 ASSERT_TRUE(response);
14675 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214676 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214677 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214678 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114679 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214680 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214681}
14682
bnc8016c1f2017-03-31 02:11:2914683// Regression test for https://crbug.com/546991.
14684// The server might not be able to serve an IP pooled request, and might send a
14685// 421 Misdirected Request response status to indicate this.
14686// HttpNetworkTransaction should reset the request and retry without IP pooling.
14687TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14688 // Two hosts resolve to the same IP address.
14689 const std::string ip_addr = "1.2.3.4";
14690 IPAddress ip;
14691 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14692 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14693
Jeremy Roman0579ed62017-08-29 15:56:1914694 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914695 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14696 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14697
14698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14699
14700 // Two requests on the first connection.
14701 SpdySerializedFrame req1(
14702 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14703 spdy_util_.UpdateWithStreamDestruction(1);
14704 SpdySerializedFrame req2(
14705 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14706 SpdySerializedFrame rst(
14707 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14708 MockWrite writes1[] = {
14709 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14710 CreateMockWrite(rst, 6),
14711 };
14712
14713 // The first one succeeds, the second gets error 421 Misdirected Request.
14714 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14715 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14716 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714717 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914718 SpdySerializedFrame resp2(
14719 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14720 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14721 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14722
14723 MockConnect connect1(ASYNC, OK, peer_addr);
14724 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14725 arraysize(writes1));
14726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14727
14728 AddSSLSocketData();
14729
14730 // Retry the second request on a second connection.
14731 SpdyTestUtil spdy_util2;
14732 SpdySerializedFrame req3(
14733 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14734 MockWrite writes2[] = {
14735 CreateMockWrite(req3, 0),
14736 };
14737
14738 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14739 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14740 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14741 MockRead(ASYNC, 0, 3)};
14742
14743 MockConnect connect2(ASYNC, OK, peer_addr);
14744 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14745 arraysize(writes2));
14746 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14747
14748 AddSSLSocketData();
14749
14750 // Preload mail.example.org into HostCache.
14751 HostPortPair host_port("mail.example.org", 443);
14752 HostResolver::RequestInfo resolve_info(host_port);
14753 AddressList ignored;
14754 std::unique_ptr<HostResolver::Request> request;
14755 TestCompletionCallback callback;
14756 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14757 &ignored, callback.callback(),
14758 &request, NetLogWithSource());
14759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14760 rv = callback.WaitForResult();
14761 EXPECT_THAT(rv, IsOk());
14762
14763 HttpRequestInfo request1;
14764 request1.method = "GET";
14765 request1.url = GURL("https://www.example.org/");
14766 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014767 request1.traffic_annotation =
14768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914769 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14770
14771 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14773 rv = callback.WaitForResult();
14774 EXPECT_THAT(rv, IsOk());
14775
14776 const HttpResponseInfo* response = trans1.GetResponseInfo();
14777 ASSERT_TRUE(response);
14778 ASSERT_TRUE(response->headers);
14779 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14780 EXPECT_TRUE(response->was_fetched_via_spdy);
14781 EXPECT_TRUE(response->was_alpn_negotiated);
14782 std::string response_data;
14783 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14784 EXPECT_EQ("hello!", response_data);
14785
14786 HttpRequestInfo request2;
14787 request2.method = "GET";
14788 request2.url = GURL("https://mail.example.org/");
14789 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014790 request2.traffic_annotation =
14791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914792 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14793
14794 BoundTestNetLog log;
14795 rv = trans2.Start(&request2, callback.callback(), log.bound());
14796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14797 rv = callback.WaitForResult();
14798 EXPECT_THAT(rv, IsOk());
14799
14800 response = trans2.GetResponseInfo();
14801 ASSERT_TRUE(response);
14802 ASSERT_TRUE(response->headers);
14803 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14804 EXPECT_TRUE(response->was_fetched_via_spdy);
14805 EXPECT_TRUE(response->was_alpn_negotiated);
14806 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14807 EXPECT_EQ("hello!", response_data);
14808
14809 TestNetLogEntry::List entries;
14810 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914811 ExpectLogContainsSomewhere(
14812 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914813 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914814}
14815
14816// Test that HTTP 421 responses are properly returned to the caller if received
14817// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14818// portions of the response.
14819TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14820 // Two hosts resolve to the same IP address.
14821 const std::string ip_addr = "1.2.3.4";
14822 IPAddress ip;
14823 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14824 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14825
Jeremy Roman0579ed62017-08-29 15:56:1914826 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914827 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14828 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14829
14830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14831
14832 // Two requests on the first connection.
14833 SpdySerializedFrame req1(
14834 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14835 spdy_util_.UpdateWithStreamDestruction(1);
14836 SpdySerializedFrame req2(
14837 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14838 SpdySerializedFrame rst(
14839 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14840 MockWrite writes1[] = {
14841 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14842 CreateMockWrite(rst, 6),
14843 };
14844
14845 // The first one succeeds, the second gets error 421 Misdirected Request.
14846 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14847 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14848 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714849 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914850 SpdySerializedFrame resp2(
14851 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14852 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14853 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14854
14855 MockConnect connect1(ASYNC, OK, peer_addr);
14856 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14857 arraysize(writes1));
14858 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14859
14860 AddSSLSocketData();
14861
14862 // Retry the second request on a second connection. It returns 421 Misdirected
14863 // Retry again.
14864 SpdyTestUtil spdy_util2;
14865 SpdySerializedFrame req3(
14866 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14867 MockWrite writes2[] = {
14868 CreateMockWrite(req3, 0),
14869 };
14870
14871 SpdySerializedFrame resp3(
14872 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14873 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14874 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14875 MockRead(ASYNC, 0, 3)};
14876
14877 MockConnect connect2(ASYNC, OK, peer_addr);
14878 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14879 arraysize(writes2));
14880 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14881
14882 AddSSLSocketData();
14883
14884 // Preload mail.example.org into HostCache.
14885 HostPortPair host_port("mail.example.org", 443);
14886 HostResolver::RequestInfo resolve_info(host_port);
14887 AddressList ignored;
14888 std::unique_ptr<HostResolver::Request> request;
14889 TestCompletionCallback callback;
14890 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14891 &ignored, callback.callback(),
14892 &request, NetLogWithSource());
14893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14894 rv = callback.WaitForResult();
14895 EXPECT_THAT(rv, IsOk());
14896
14897 HttpRequestInfo request1;
14898 request1.method = "GET";
14899 request1.url = GURL("https://www.example.org/");
14900 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014901 request1.traffic_annotation =
14902 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914903 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14904
14905 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14907 rv = callback.WaitForResult();
14908 EXPECT_THAT(rv, IsOk());
14909
14910 const HttpResponseInfo* response = trans1.GetResponseInfo();
14911 ASSERT_TRUE(response);
14912 ASSERT_TRUE(response->headers);
14913 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14914 EXPECT_TRUE(response->was_fetched_via_spdy);
14915 EXPECT_TRUE(response->was_alpn_negotiated);
14916 std::string response_data;
14917 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14918 EXPECT_EQ("hello!", response_data);
14919
14920 HttpRequestInfo request2;
14921 request2.method = "GET";
14922 request2.url = GURL("https://mail.example.org/");
14923 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014924 request2.traffic_annotation =
14925 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914926 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14927
14928 BoundTestNetLog log;
14929 rv = trans2.Start(&request2, callback.callback(), log.bound());
14930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14931 rv = callback.WaitForResult();
14932 EXPECT_THAT(rv, IsOk());
14933
14934 // After a retry, the 421 Misdirected Request is reported back up to the
14935 // caller.
14936 response = trans2.GetResponseInfo();
14937 ASSERT_TRUE(response);
14938 ASSERT_TRUE(response->headers);
14939 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14940 EXPECT_TRUE(response->was_fetched_via_spdy);
14941 EXPECT_TRUE(response->was_alpn_negotiated);
14942 EXPECT_TRUE(response->ssl_info.cert);
14943 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14944 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914945}
14946
bnc6dcd8192017-05-25 20:11:5014947class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614948 public:
14949 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014950 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714951 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614952
dchengb03027d2014-10-21 12:00:2014953 int ResolveFromCache(const RequestInfo& info,
14954 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014955 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014956 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014957 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014958 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614959 return rv;
14960 }
14961
[email protected]e3ceb682011-06-28 23:55:4614962 private:
[email protected]e3ceb682011-06-28 23:55:4614963 const HostPortPair host_port_;
14964};
14965
bncd16676a2016-07-20 16:23:0114966TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314967 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614968 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914969 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714970 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914971 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614972
bnc032658ba2016-09-26 18:17:1514973 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614974
bncdf80d44fd2016-07-15 20:27:4114975 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914976 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814977 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114978 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714979 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614980 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114981 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614982 };
bnc42331402016-07-25 13:36:1514983 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114984 SpdySerializedFrame host1_resp_body(
14985 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514986 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114987 SpdySerializedFrame host2_resp_body(
14988 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614989 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114990 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14991 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314992 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614993 };
14994
eroman36d84e54432016-03-17 03:23:0214995 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214996 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314997 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14998 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714999 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615000
[email protected]aa22b242011-11-16 18:58:2915001 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615002 HttpRequestInfo request1;
15003 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315004 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615005 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015006 request1.traffic_annotation =
15007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015008 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615009
tfarina42834112016-09-22 13:38:2015010 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115011 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15012 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615013
15014 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215015 ASSERT_TRUE(response);
15016 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215017 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615018
15019 std::string response_data;
robpercival214763f2016-07-01 23:27:0115020 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615021 EXPECT_EQ("hello!", response_data);
15022
15023 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715024 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615025 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015026 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015027 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15028 &ignored, callback.callback(),
15029 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715031 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115032 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615033
15034 HttpRequestInfo request2;
15035 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715036 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615037 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015038 request2.traffic_annotation =
15039 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015040 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615041
tfarina42834112016-09-22 13:38:2015042 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15044 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615045
15046 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215047 ASSERT_TRUE(response);
15048 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215049 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615050 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215051 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115052 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615053 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615054}
15055
bncd16676a2016-07-20 16:23:0115056TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315057 const std::string https_url = "https://www.example.org:8080/";
15058 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415059
15060 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115061 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915062 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415063
15064 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115065 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415066 };
15067
bnc42331402016-07-25 13:36:1515068 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115069 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15070 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915071 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415072
rch8e6c6c42015-05-01 14:05:1315073 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15074 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415075 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715076 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415077
15078 // HTTP GET for the HTTP URL
15079 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315080 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415081 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315082 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415083 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415084 };
15085
15086 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315087 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15088 MockRead(ASYNC, 2, "hello"),
15089 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415090 };
15091
rch8e6c6c42015-05-01 14:05:1315092 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15093 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0415094
[email protected]8450d722012-07-02 19:14:0415095 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615096 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15098 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15099 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415100
danakj1fd259a02016-04-16 03:17:0915101 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415102
15103 // Start the first transaction to set up the SpdySession
15104 HttpRequestInfo request1;
15105 request1.method = "GET";
15106 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415107 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015108 request1.traffic_annotation =
15109 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015110 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415111 TestCompletionCallback callback1;
15112 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015113 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515114 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415115
robpercival214763f2016-07-01 23:27:0115116 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415117 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15118
15119 // Now, start the HTTP request
15120 HttpRequestInfo request2;
15121 request2.method = "GET";
15122 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415123 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015124 request2.traffic_annotation =
15125 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015126 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415127 TestCompletionCallback callback2;
15128 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015129 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515130 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415131
robpercival214763f2016-07-01 23:27:0115132 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415133 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15134}
15135
bnc5452e2a2015-05-08 16:27:4215136// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15137// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115138TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515139 url::SchemeHostPort server("https", "www.example.org", 443);
15140 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215141
bnc8bef8da22016-05-30 01:28:2515142 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215143 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615144 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15146
15147 // No data should be read from the alternative, because HTTP/1.1 is
15148 // negotiated.
15149 StaticSocketDataProvider data;
15150 session_deps_.socket_factory->AddSocketDataProvider(&data);
15151
15152 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615153 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215154 // mocked. This way the request relies on the alternate Job.
15155 StaticSocketDataProvider data_refused;
15156 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15157 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15158
zhongyi3d4a55e72016-04-22 20:36:4615159 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915160 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015161 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215162 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115163 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215164 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115165 http_server_properties->SetHttp2AlternativeService(
15166 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215167
bnc5452e2a2015-05-08 16:27:4215168 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215170 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515171 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1015172 request.traffic_annotation =
15173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215174 TestCompletionCallback callback;
15175
15176 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215177 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015178 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215179 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215180}
15181
bnc40448a532015-05-11 19:13:1415182// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615183// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415184// succeeds, the request should succeed, even if the latter fails because
15185// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115186TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515187 url::SchemeHostPort server("https", "www.example.org", 443);
15188 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415189
15190 // Negotiate HTTP/1.1 with alternative.
15191 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615192 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415193 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15194
15195 // No data should be read from the alternative, because HTTP/1.1 is
15196 // negotiated.
15197 StaticSocketDataProvider data;
15198 session_deps_.socket_factory->AddSocketDataProvider(&data);
15199
zhongyi3d4a55e72016-04-22 20:36:4615200 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415201 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615202 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415203 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15204
15205 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515206 MockWrite("GET / HTTP/1.1\r\n"
15207 "Host: www.example.org\r\n"
15208 "Connection: keep-alive\r\n\r\n"),
15209 MockWrite("GET /second HTTP/1.1\r\n"
15210 "Host: www.example.org\r\n"
15211 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415212 };
15213
15214 MockRead http_reads[] = {
15215 MockRead("HTTP/1.1 200 OK\r\n"),
15216 MockRead("Content-Type: text/html\r\n"),
15217 MockRead("Content-Length: 6\r\n\r\n"),
15218 MockRead("foobar"),
15219 MockRead("HTTP/1.1 200 OK\r\n"),
15220 MockRead("Content-Type: text/html\r\n"),
15221 MockRead("Content-Length: 7\r\n\r\n"),
15222 MockRead("another"),
15223 };
15224 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15225 http_writes, arraysize(http_writes));
15226 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15227
zhongyi3d4a55e72016-04-22 20:36:4615228 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015230 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415231 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115232 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215233 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115234 http_server_properties->SetHttp2AlternativeService(
15235 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415236
15237 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15238 HttpRequestInfo request1;
15239 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515240 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415241 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015242 request1.traffic_annotation =
15243 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415244 TestCompletionCallback callback1;
15245
tfarina42834112016-09-22 13:38:2015246 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415247 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115248 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415249
15250 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215251 ASSERT_TRUE(response1);
15252 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415253 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15254
15255 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115256 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415257 EXPECT_EQ("foobar", response_data1);
15258
15259 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15260 // for alternative service.
15261 EXPECT_TRUE(
15262 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15263
zhongyi3d4a55e72016-04-22 20:36:4615264 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415265 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615266 // to server.
bnc40448a532015-05-11 19:13:1415267 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15268 HttpRequestInfo request2;
15269 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515270 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415271 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015272 request2.traffic_annotation =
15273 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415274 TestCompletionCallback callback2;
15275
tfarina42834112016-09-22 13:38:2015276 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415277 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115278 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415279
15280 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215281 ASSERT_TRUE(response2);
15282 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415283 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15284
15285 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115286 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415287 EXPECT_EQ("another", response_data2);
15288}
15289
bnc5452e2a2015-05-08 16:27:4215290// Alternative service requires HTTP/2 (or SPDY), but there is already a
15291// HTTP/1.1 socket open to the alternative server. That socket should not be
15292// used.
bncd16676a2016-07-20 16:23:0115293TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615294 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215295 HostPortPair alternative("alternative.example.org", 443);
15296 std::string origin_url = "https://origin.example.org:443";
15297 std::string alternative_url = "https://alternative.example.org:443";
15298
15299 // Negotiate HTTP/1.1 with alternative.example.org.
15300 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615301 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15303
15304 // HTTP/1.1 data for |request1| and |request2|.
15305 MockWrite http_writes[] = {
15306 MockWrite(
15307 "GET / HTTP/1.1\r\n"
15308 "Host: alternative.example.org\r\n"
15309 "Connection: keep-alive\r\n\r\n"),
15310 MockWrite(
15311 "GET / HTTP/1.1\r\n"
15312 "Host: alternative.example.org\r\n"
15313 "Connection: keep-alive\r\n\r\n"),
15314 };
15315
15316 MockRead http_reads[] = {
15317 MockRead(
15318 "HTTP/1.1 200 OK\r\n"
15319 "Content-Type: text/html; charset=iso-8859-1\r\n"
15320 "Content-Length: 40\r\n\r\n"
15321 "first HTTP/1.1 response from alternative"),
15322 MockRead(
15323 "HTTP/1.1 200 OK\r\n"
15324 "Content-Type: text/html; charset=iso-8859-1\r\n"
15325 "Content-Length: 41\r\n\r\n"
15326 "second HTTP/1.1 response from alternative"),
15327 };
15328 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15329 http_writes, arraysize(http_writes));
15330 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15331
15332 // This test documents that an alternate Job should not pool to an already
15333 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615334 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215335 StaticSocketDataProvider data_refused;
15336 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15337 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15338
zhongyi3d4a55e72016-04-22 20:36:4615339 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015341 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215342 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115343 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215344 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115345 http_server_properties->SetHttp2AlternativeService(
15346 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215347
15348 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215349 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615350 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215351 request1.method = "GET";
15352 request1.url = GURL(alternative_url);
15353 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015354 request1.traffic_annotation =
15355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215356 TestCompletionCallback callback1;
15357
tfarina42834112016-09-22 13:38:2015358 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115359 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615360 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215361 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215362 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215363 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215364 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215365 EXPECT_FALSE(response1->was_fetched_via_spdy);
15366 std::string response_data1;
bnc691fda62016-08-12 00:43:1615367 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215368 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15369
15370 // Request for origin.example.org, which has an alternative service. This
15371 // will start two Jobs: the alternative looks for connections to pool to,
15372 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615373 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215374 // this request fails.
bnc5452e2a2015-05-08 16:27:4215375 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615376 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215377 request2.method = "GET";
15378 request2.url = GURL(origin_url);
15379 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015380 request2.traffic_annotation =
15381 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215382 TestCompletionCallback callback2;
15383
tfarina42834112016-09-22 13:38:2015384 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115385 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215386
15387 // Another transaction to alternative. This is to test that the HTTP/1.1
15388 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215389 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615390 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215391 request3.method = "GET";
15392 request3.url = GURL(alternative_url);
15393 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015394 request3.traffic_annotation =
15395 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215396 TestCompletionCallback callback3;
15397
tfarina42834112016-09-22 13:38:2015398 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115399 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615400 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215401 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215402 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215403 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215404 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215405 EXPECT_FALSE(response3->was_fetched_via_spdy);
15406 std::string response_data3;
bnc691fda62016-08-12 00:43:1615407 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215408 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15409}
15410
bncd16676a2016-07-20 16:23:0115411TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315412 const std::string https_url = "https://www.example.org:8080/";
15413 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415414
rdsmithebb50aa2015-11-12 03:44:3815415 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115416 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815417
[email protected]8450d722012-07-02 19:14:0415418 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315419 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115420 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415421 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115422 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915423 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115424 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215425 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915426
15427 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915428 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715429 req2_block[kHttp2MethodHeader] = "GET";
15430 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15431 req2_block[kHttp2SchemeHeader] = "http";
15432 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115433 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515434 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415435
15436 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115437 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15438 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415439 };
15440
bncdf80d44fd2016-07-15 20:27:4115441 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515442 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115443 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515444 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115445 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15446 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815447 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115448 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815449 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515450 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115451 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315452 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115453 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315454 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115455 CreateMockRead(wrapped_resp1, 4),
15456 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315457 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115458 CreateMockRead(resp2, 8),
15459 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315460 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15461 };
[email protected]8450d722012-07-02 19:14:0415462
mmenke666a6fea2015-12-19 04:16:3315463 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15464 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415465 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715466 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415467
Lily Houghton8c2f97d2018-01-22 05:06:5915468 session_deps_.proxy_resolution_service =
15469 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115470 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715471 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415472 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615473 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315474 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415475 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615476 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315477 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15478 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415479
danakj1fd259a02016-04-16 03:17:0915480 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415481
15482 // Start the first transaction to set up the SpdySession
15483 HttpRequestInfo request1;
15484 request1.method = "GET";
15485 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415486 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015487 request1.traffic_annotation =
15488 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015489 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415490 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015491 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415492
mmenke666a6fea2015-12-19 04:16:3315493 // This pause is a hack to avoid running into https://crbug.com/497228.
15494 data1.RunUntilPaused();
15495 base::RunLoop().RunUntilIdle();
15496 data1.Resume();
robpercival214763f2016-07-01 23:27:0115497 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415498 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15499
[email protected]f6c63db52013-02-02 00:35:2215500 LoadTimingInfo load_timing_info1;
15501 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15502 TestLoadTimingNotReusedWithPac(load_timing_info1,
15503 CONNECT_TIMING_HAS_SSL_TIMES);
15504
mmenke666a6fea2015-12-19 04:16:3315505 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415506 HttpRequestInfo request2;
15507 request2.method = "GET";
15508 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415509 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015510 request2.traffic_annotation =
15511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015512 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415513 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015514 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415515
mmenke666a6fea2015-12-19 04:16:3315516 // This pause is a hack to avoid running into https://crbug.com/497228.
15517 data1.RunUntilPaused();
15518 base::RunLoop().RunUntilIdle();
15519 data1.Resume();
robpercival214763f2016-07-01 23:27:0115520 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315521
[email protected]8450d722012-07-02 19:14:0415522 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215523
15524 LoadTimingInfo load_timing_info2;
15525 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15526 // The established SPDY sessions is considered reused by the HTTP request.
15527 TestLoadTimingReusedWithPac(load_timing_info2);
15528 // HTTP requests over a SPDY session should have a different connection
15529 // socket_log_id than requests over a tunnel.
15530 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415531}
15532
[email protected]2d88e7d2012-07-19 17:55:1715533// Test that in the case where we have a SPDY session to a SPDY proxy
15534// that we do not pool other origins that resolve to the same IP when
15535// the certificate does not match the new origin.
15536// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115537TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315538 const std::string url1 = "http://www.example.org/";
15539 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715540 const std::string ip_addr = "1.2.3.4";
15541
rdsmithebb50aa2015-11-12 03:44:3815542 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115543 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815544
[email protected]2d88e7d2012-07-19 17:55:1715545 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615546 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315547 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115548 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515549 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715550
15551 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115552 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715553 };
15554
bnc42331402016-07-25 13:36:1515555 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115556 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715557 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115558 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15559 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715560 };
15561
mmenke666a6fea2015-12-19 04:16:3315562 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15563 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215564 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915565 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715566 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15567 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315568 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715569
15570 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115571 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915572 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715573
15574 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115575 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715576 };
15577
bnc42331402016-07-25 13:36:1515578 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115579 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15580 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315581 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715582
mmenke666a6fea2015-12-19 04:16:3315583 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15584 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715585 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315586 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715587
15588 // Set up a proxy config that sends HTTP requests to a proxy, and
15589 // all others direct.
15590 ProxyConfig proxy_config;
15591 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Lily Houghton8c2f97d2018-01-22 05:06:5915592 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1915593 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815594 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715595
bncce36dca22015-04-21 22:11:2315596 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615597 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715598 // Load a valid cert. Note, that this does not need to
15599 // be valid for proxy because the MockSSLClientSocket does
15600 // not actually verify it. But SpdySession will use this
15601 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915602 ssl1.ssl_info.cert =
15603 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15604 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15606 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715607
15608 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615609 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15611 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715612
Jeremy Roman0579ed62017-08-29 15:56:1915613 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315614 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715615 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715616
danakj1fd259a02016-04-16 03:17:0915617 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715618
15619 // Start the first transaction to set up the SpdySession
15620 HttpRequestInfo request1;
15621 request1.method = "GET";
15622 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715623 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015624 request1.traffic_annotation =
15625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015626 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715627 TestCompletionCallback callback1;
15628 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015629 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315630 // This pause is a hack to avoid running into https://crbug.com/497228.
15631 data1.RunUntilPaused();
15632 base::RunLoop().RunUntilIdle();
15633 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715634
robpercival214763f2016-07-01 23:27:0115635 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715636 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15637
15638 // Now, start the HTTP request
15639 HttpRequestInfo request2;
15640 request2.method = "GET";
15641 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715642 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015643 request2.traffic_annotation =
15644 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015645 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715646 TestCompletionCallback callback2;
15647 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015648 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515649 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715650
15651 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115652 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715653 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15654}
15655
[email protected]85f97342013-04-17 06:12:2415656// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15657// error) in SPDY session, removes the socket from pool and closes the SPDY
15658// session. Verify that new url's from the same HttpNetworkSession (and a new
15659// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115660TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315661 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415662
15663 MockRead reads1[] = {
15664 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15665 };
15666
mmenke11eb5152015-06-09 14:50:5015667 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415668
bncdf80d44fd2016-07-15 20:27:4115669 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915670 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415671 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115672 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415673 };
15674
bnc42331402016-07-25 13:36:1515675 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115676 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415677 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115678 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15679 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415680 };
15681
mmenke11eb5152015-06-09 14:50:5015682 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15683 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415684
[email protected]85f97342013-04-17 06:12:2415685 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615686 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15688 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415689
15690 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615691 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015692 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15693 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415694
danakj1fd259a02016-04-16 03:17:0915695 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015696 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415697
15698 // Start the first transaction to set up the SpdySession and verify that
15699 // connection was closed.
15700 HttpRequestInfo request1;
15701 request1.method = "GET";
15702 request1.url = GURL(https_url);
15703 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015704 request1.traffic_annotation =
15705 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015706 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415707 TestCompletionCallback callback1;
15708 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015709 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115710 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415711
15712 // Now, start the second request and make sure it succeeds.
15713 HttpRequestInfo request2;
15714 request2.method = "GET";
15715 request2.url = GURL(https_url);
15716 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015717 request2.traffic_annotation =
15718 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015719 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415720 TestCompletionCallback callback2;
15721 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015722 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415723
robpercival214763f2016-07-01 23:27:0115724 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415725 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15726}
15727
bncd16676a2016-07-20 16:23:0115728TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315729 ClientSocketPoolManager::set_max_sockets_per_group(
15730 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15731 ClientSocketPoolManager::set_max_sockets_per_pool(
15732 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15733
15734 // Use two different hosts with different IPs so they don't get pooled.
15735 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15736 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315738
15739 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615740 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315741 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615742 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315743 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15745
bncdf80d44fd2016-07-15 20:27:4115746 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915747 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315748 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115749 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315750 };
bnc42331402016-07-25 13:36:1515751 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115752 SpdySerializedFrame host1_resp_body(
15753 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315754 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115755 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915756 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315757 };
15758
rdsmithebb50aa2015-11-12 03:44:3815759 // Use a separate test instance for the separate SpdySession that will be
15760 // created.
bncd16676a2016-07-20 16:23:0115761 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915762 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815763 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15764 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315765 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15766
bncdf80d44fd2016-07-15 20:27:4115767 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915768 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315769 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115770 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315771 };
bnc42331402016-07-25 13:36:1515772 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115773 SpdySerializedFrame host2_resp_body(
15774 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315775 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115776 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915777 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315778 };
15779
Jeremy Roman0579ed62017-08-29 15:56:1915780 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815781 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15782 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315783 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15784
15785 MockWrite http_write[] = {
15786 MockWrite("GET / HTTP/1.1\r\n"
15787 "Host: www.a.com\r\n"
15788 "Connection: keep-alive\r\n\r\n"),
15789 };
15790
15791 MockRead http_read[] = {
15792 MockRead("HTTP/1.1 200 OK\r\n"),
15793 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15794 MockRead("Content-Length: 6\r\n\r\n"),
15795 MockRead("hello!"),
15796 };
15797 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15798 http_write, arraysize(http_write));
15799 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15800
15801 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415802 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15803 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315804 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615805 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315806
15807 TestCompletionCallback callback;
15808 HttpRequestInfo request1;
15809 request1.method = "GET";
15810 request1.url = GURL("https://www.a.com/");
15811 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015812 request1.traffic_annotation =
15813 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815814 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915815 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315816
tfarina42834112016-09-22 13:38:2015817 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15819 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315820
15821 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215822 ASSERT_TRUE(response);
15823 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215824 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315825 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215826 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315827
15828 std::string response_data;
robpercival214763f2016-07-01 23:27:0115829 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315830 EXPECT_EQ("hello!", response_data);
15831 trans.reset();
15832 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615833 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315834
15835 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415836 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15837 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315838 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615839 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315840 HttpRequestInfo request2;
15841 request2.method = "GET";
15842 request2.url = GURL("https://www.b.com/");
15843 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015844 request2.traffic_annotation =
15845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815846 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915847 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315848
tfarina42834112016-09-22 13:38:2015849 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115850 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15851 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315852
15853 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215854 ASSERT_TRUE(response);
15855 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215856 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315857 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215858 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115859 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315860 EXPECT_EQ("hello!", response_data);
15861 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615862 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315863 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615864 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315865
15866 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415867 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15868 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315869 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615870 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315871 HttpRequestInfo request3;
15872 request3.method = "GET";
15873 request3.url = GURL("http://www.a.com/");
15874 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015875 request3.traffic_annotation =
15876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815877 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315879
tfarina42834112016-09-22 13:38:2015880 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15882 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315883
15884 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215885 ASSERT_TRUE(response);
15886 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315887 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15888 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215889 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115890 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315891 EXPECT_EQ("hello!", response_data);
15892 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615893 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315894 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615895 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315896}
15897
bncd16676a2016-07-20 16:23:0115898TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415899 HttpRequestInfo request;
15900 request.method = "GET";
bncce36dca22015-04-21 22:11:2315901 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015902 request.traffic_annotation =
15903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415904
danakj1fd259a02016-04-16 03:17:0915905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615906 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415907
ttuttled9dbc652015-09-29 20:00:5915908 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415909 StaticSocketDataProvider data;
15910 data.set_connect_data(mock_connect);
15911 session_deps_.socket_factory->AddSocketDataProvider(&data);
15912
15913 TestCompletionCallback callback;
15914
tfarina42834112016-09-22 13:38:2015915 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115916 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415917
15918 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115919 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415920
[email protected]79e1fd62013-06-20 06:50:0415921 // We don't care whether this succeeds or fails, but it shouldn't crash.
15922 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615923 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715924
15925 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615926 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715927 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115928 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915929
15930 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615931 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915932 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415933}
15934
bncd16676a2016-07-20 16:23:0115935TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415936 HttpRequestInfo request;
15937 request.method = "GET";
bncce36dca22015-04-21 22:11:2315938 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015939 request.traffic_annotation =
15940 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415941
danakj1fd259a02016-04-16 03:17:0915942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415944
ttuttled9dbc652015-09-29 20:00:5915945 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415946 StaticSocketDataProvider data;
15947 data.set_connect_data(mock_connect);
15948 session_deps_.socket_factory->AddSocketDataProvider(&data);
15949
15950 TestCompletionCallback callback;
15951
tfarina42834112016-09-22 13:38:2015952 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415954
15955 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115956 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415957
[email protected]79e1fd62013-06-20 06:50:0415958 // We don't care whether this succeeds or fails, but it shouldn't crash.
15959 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615960 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715961
15962 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615963 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715964 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115965 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915966
15967 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615968 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915969 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415970}
15971
bncd16676a2016-07-20 16:23:0115972TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415973 HttpRequestInfo request;
15974 request.method = "GET";
bncce36dca22015-04-21 22:11:2315975 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015976 request.traffic_annotation =
15977 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415978
danakj1fd259a02016-04-16 03:17:0915979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415981
15982 MockWrite data_writes[] = {
15983 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15984 };
15985 MockRead data_reads[] = {
15986 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15987 };
15988
15989 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15990 data_writes, arraysize(data_writes));
15991 session_deps_.socket_factory->AddSocketDataProvider(&data);
15992
15993 TestCompletionCallback callback;
15994
tfarina42834112016-09-22 13:38:2015995 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415997
15998 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115999 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416000
[email protected]79e1fd62013-06-20 06:50:0416001 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616002 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416003 EXPECT_TRUE(request_headers.HasHeader("Host"));
16004}
16005
bncd16676a2016-07-20 16:23:0116006TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416007 HttpRequestInfo request;
16008 request.method = "GET";
bncce36dca22015-04-21 22:11:2316009 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016010 request.traffic_annotation =
16011 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416012
danakj1fd259a02016-04-16 03:17:0916013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416015
16016 MockWrite data_writes[] = {
16017 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16018 };
16019 MockRead data_reads[] = {
16020 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16021 };
16022
16023 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16024 data_writes, arraysize(data_writes));
16025 session_deps_.socket_factory->AddSocketDataProvider(&data);
16026
16027 TestCompletionCallback callback;
16028
tfarina42834112016-09-22 13:38:2016029 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416031
16032 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116033 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416034
[email protected]79e1fd62013-06-20 06:50:0416035 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616036 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416037 EXPECT_TRUE(request_headers.HasHeader("Host"));
16038}
16039
bncd16676a2016-07-20 16:23:0116040TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416041 HttpRequestInfo request;
16042 request.method = "GET";
bncce36dca22015-04-21 22:11:2316043 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016044 request.traffic_annotation =
16045 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416046
danakj1fd259a02016-04-16 03:17:0916047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616048 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416049
16050 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316051 MockWrite(
16052 "GET / HTTP/1.1\r\n"
16053 "Host: www.example.org\r\n"
16054 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416055 };
16056 MockRead data_reads[] = {
16057 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16058 };
16059
16060 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16061 data_writes, arraysize(data_writes));
16062 session_deps_.socket_factory->AddSocketDataProvider(&data);
16063
16064 TestCompletionCallback callback;
16065
tfarina42834112016-09-22 13:38:2016066 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416068
16069 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116070 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416071
[email protected]79e1fd62013-06-20 06:50:0416072 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616073 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416074 EXPECT_TRUE(request_headers.HasHeader("Host"));
16075}
16076
bncd16676a2016-07-20 16:23:0116077TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416078 HttpRequestInfo request;
16079 request.method = "GET";
bncce36dca22015-04-21 22:11:2316080 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016081 request.traffic_annotation =
16082 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416083
danakj1fd259a02016-04-16 03:17:0916084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416086
16087 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316088 MockWrite(
16089 "GET / HTTP/1.1\r\n"
16090 "Host: www.example.org\r\n"
16091 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416092 };
16093 MockRead data_reads[] = {
16094 MockRead(ASYNC, ERR_CONNECTION_RESET),
16095 };
16096
16097 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16098 data_writes, arraysize(data_writes));
16099 session_deps_.socket_factory->AddSocketDataProvider(&data);
16100
16101 TestCompletionCallback callback;
16102
tfarina42834112016-09-22 13:38:2016103 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116104 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416105
16106 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116107 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416108
[email protected]79e1fd62013-06-20 06:50:0416109 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616110 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416111 EXPECT_TRUE(request_headers.HasHeader("Host"));
16112}
16113
bncd16676a2016-07-20 16:23:0116114TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416115 HttpRequestInfo request;
16116 request.method = "GET";
bncce36dca22015-04-21 22:11:2316117 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416118 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016119 request.traffic_annotation =
16120 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416121
danakj1fd259a02016-04-16 03:17:0916122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416124
16125 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316126 MockWrite(
16127 "GET / HTTP/1.1\r\n"
16128 "Host: www.example.org\r\n"
16129 "Connection: keep-alive\r\n"
16130 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416131 };
16132 MockRead data_reads[] = {
16133 MockRead("HTTP/1.1 200 OK\r\n"
16134 "Content-Length: 5\r\n\r\n"
16135 "hello"),
16136 MockRead(ASYNC, ERR_UNEXPECTED),
16137 };
16138
16139 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16140 data_writes, arraysize(data_writes));
16141 session_deps_.socket_factory->AddSocketDataProvider(&data);
16142
16143 TestCompletionCallback callback;
16144
tfarina42834112016-09-22 13:38:2016145 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416147
16148 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116149 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416150
16151 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616152 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416153 std::string foo;
16154 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16155 EXPECT_EQ("bar", foo);
16156}
16157
[email protected]bf828982013-08-14 18:01:4716158namespace {
16159
yhiranoa7e05bb2014-11-06 05:40:3916160// Fake HttpStream that simply records calls to SetPriority().
16161class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0316162 public base::SupportsWeakPtr<FakeStream> {
16163 public:
16164 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2716165 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0316166
16167 RequestPriority priority() const { return priority_; }
16168
dchengb03027d2014-10-21 12:00:2016169 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716170 bool can_send_early,
dchengb03027d2014-10-21 12:00:2016171 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016172 const NetLogWithSource& net_log,
Bence Békya25e3f72018-02-13 21:13:3916173 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316174 return ERR_IO_PENDING;
16175 }
16176
dchengb03027d2014-10-21 12:00:2016177 int SendRequest(const HttpRequestHeaders& request_headers,
16178 HttpResponseInfo* response,
Bence Békya25e3f72018-02-13 21:13:3916179 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316180 ADD_FAILURE();
16181 return ERR_UNEXPECTED;
16182 }
16183
Bence Békya25e3f72018-02-13 21:13:3916184 int ReadResponseHeaders(CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316185 ADD_FAILURE();
16186 return ERR_UNEXPECTED;
16187 }
16188
dchengb03027d2014-10-21 12:00:2016189 int ReadResponseBody(IOBuffer* buf,
16190 int buf_len,
Bence Békya25e3f72018-02-13 21:13:3916191 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316192 ADD_FAILURE();
16193 return ERR_UNEXPECTED;
16194 }
16195
dchengb03027d2014-10-21 12:00:2016196 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0316197
dchengb03027d2014-10-21 12:00:2016198 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0316199 ADD_FAILURE();
16200 return false;
16201 }
16202
dchengb03027d2014-10-21 12:00:2016203 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0316204 ADD_FAILURE();
16205 return false;
16206 }
16207
dchengb03027d2014-10-21 12:00:2016208 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316209
mmenkebd84c392015-09-02 14:12:3416210 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0316211
sclittle4de1bab92015-09-22 21:28:2416212 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5916213 ADD_FAILURE();
16214 return 0;
16215 }
16216
sclittlebe1ccf62015-09-02 19:40:3616217 int64_t GetTotalSentBytes() const override {
16218 ADD_FAILURE();
16219 return 0;
16220 }
16221
dchengb03027d2014-10-21 12:00:2016222 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0316223 ADD_FAILURE();
16224 return false;
16225 }
16226
rchcd379012017-04-12 21:53:3216227 bool GetAlternativeService(
16228 AlternativeService* alternative_service) const override {
16229 ADD_FAILURE();
16230 return false;
16231 }
16232
dchengb03027d2014-10-21 12:00:2016233 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
16234
16235 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0316236 ADD_FAILURE();
16237 }
16238
ttuttled9dbc652015-09-29 20:00:5916239 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16240
nharper78e6d2b2016-09-21 05:42:3516241 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16242 TokenBindingType tb_type,
16243 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416244 ADD_FAILURE();
16245 return ERR_NOT_IMPLEMENTED;
16246 }
16247
dchengb03027d2014-10-21 12:00:2016248 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316249
zhongyica364fbb2015-12-12 03:39:1216250 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16251
dchengb03027d2014-10-21 12:00:2016252 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0316253
yhiranoa7e05bb2014-11-06 05:40:3916254 HttpStream* RenewStreamForAuth() override { return NULL; }
16255
Andrey Kosyakov83a6eee2017-08-14 19:20:0416256 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
16257
[email protected]e86839fd2013-08-14 18:29:0316258 private:
16259 RequestPriority priority_;
16260
16261 DISALLOW_COPY_AND_ASSIGN(FakeStream);
16262};
16263
16264// Fake HttpStreamRequest that simply records calls to SetPriority()
16265// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4716266class FakeStreamRequest : public HttpStreamRequest,
16267 public base::SupportsWeakPtr<FakeStreamRequest> {
16268 public:
[email protected]e86839fd2013-08-14 18:29:0316269 FakeStreamRequest(RequestPriority priority,
16270 HttpStreamRequest::Delegate* delegate)
16271 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4416272 delegate_(delegate),
16273 websocket_stream_create_helper_(NULL) {}
16274
16275 FakeStreamRequest(RequestPriority priority,
16276 HttpStreamRequest::Delegate* delegate,
16277 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
16278 : priority_(priority),
16279 delegate_(delegate),
16280 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0316281
Chris Watkins7a41d3552017-12-01 02:13:2716282 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4716283
16284 RequestPriority priority() const { return priority_; }
16285
[email protected]831e4a32013-11-14 02:14:4416286 const WebSocketHandshakeStreamBase::CreateHelper*
16287 websocket_stream_create_helper() const {
16288 return websocket_stream_create_helper_;
16289 }
16290
[email protected]e86839fd2013-08-14 18:29:0316291 // Create a new FakeStream and pass it to the request's
16292 // delegate. Returns a weak pointer to the FakeStream.
16293 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1916294 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0316295 // Do this before calling OnStreamReady() as OnStreamReady() may
16296 // immediately delete |fake_stream|.
16297 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0016298 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0316299 return weak_stream;
16300 }
16301
asanka681f02d2017-02-22 17:06:3916302 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4716303 ADD_FAILURE();
16304 return ERR_UNEXPECTED;
16305 }
16306
dchengb03027d2014-10-21 12:00:2016307 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4716308 ADD_FAILURE();
16309 return LoadState();
16310 }
16311
dchengb03027d2014-10-21 12:00:2016312 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4716313
bnc94c92842016-09-21 15:22:5216314 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716315
bnc6227b26e2016-08-12 02:00:4316316 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4716317
dchengb03027d2014-10-21 12:00:2016318 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716319
ttuttle1f2d7e92015-04-28 16:17:4716320 const ConnectionAttempts& connection_attempts() const override {
16321 static ConnectionAttempts no_attempts;
16322 return no_attempts;
16323 }
16324
[email protected]bf828982013-08-14 18:01:4716325 private:
16326 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0316327 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4416328 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4716329
16330 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
16331};
16332
16333// Fake HttpStreamFactory that vends FakeStreamRequests.
16334class FakeStreamFactory : public HttpStreamFactory {
16335 public:
Chris Watkins7a41d3552017-12-01 02:13:2716336 FakeStreamFactory() = default;
16337 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4716338
16339 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
16340 // RequestStream() (which may be NULL if it was destroyed already).
16341 base::WeakPtr<FakeStreamRequest> last_stream_request() {
16342 return last_stream_request_;
16343 }
16344
xunjieli96f2a402017-06-05 17:24:2716345 std::unique_ptr<HttpStreamRequest> RequestStream(
16346 const HttpRequestInfo& info,
16347 RequestPriority priority,
16348 const SSLConfig& server_ssl_config,
16349 const SSLConfig& proxy_ssl_config,
16350 HttpStreamRequest::Delegate* delegate,
16351 bool enable_ip_based_pooling,
16352 bool enable_alternative_services,
16353 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1916354 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4716355 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716356 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716357 }
16358
xunjieli96f2a402017-06-05 17:24:2716359 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0816360 const HttpRequestInfo& info,
16361 RequestPriority priority,
16362 const SSLConfig& server_ssl_config,
16363 const SSLConfig& proxy_ssl_config,
16364 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2916365 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616366 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016367 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0816368 NOTREACHED();
16369 return nullptr;
16370 }
16371
xunjieli96f2a402017-06-05 17:24:2716372 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4716373 const HttpRequestInfo& info,
16374 RequestPriority priority,
16375 const SSLConfig& server_ssl_config,
16376 const SSLConfig& proxy_ssl_config,
16377 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4616378 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2916379 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616380 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016381 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2716382 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1916383 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4416384 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716385 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716386 }
16387
dchengb03027d2014-10-21 12:00:2016388 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5916389 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4716390 ADD_FAILURE();
16391 }
16392
dchengb03027d2014-10-21 12:00:2016393 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4716394 ADD_FAILURE();
16395 return NULL;
16396 }
16397
xunjielif5267de2017-01-20 21:18:5716398 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
16399 const std::string& parent_absolute_name) const override {
16400 ADD_FAILURE();
16401 }
16402
[email protected]bf828982013-08-14 18:01:4716403 private:
16404 base::WeakPtr<FakeStreamRequest> last_stream_request_;
16405
16406 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16407};
16408
[email protected]bf828982013-08-14 18:01:4716409} // namespace
16410
16411// Make sure that HttpNetworkTransaction passes on its priority to its
16412// stream request on start.
bncd16676a2016-07-20 16:23:0116413TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916414 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216415 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716416 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916417 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716418
krasinc06a72a2016-12-21 03:42:4616419 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116420 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716421
Ramin Halavatib5e433e62018-02-07 07:41:1016422 request.traffic_annotation =
16423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16424
wezca1070932016-05-26 20:30:5216425 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716426
[email protected]bf828982013-08-14 18:01:4716427 TestCompletionCallback callback;
16428 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016429 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716430
16431 base::WeakPtr<FakeStreamRequest> fake_request =
16432 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216433 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716434 EXPECT_EQ(LOW, fake_request->priority());
16435}
16436
16437// Make sure that HttpNetworkTransaction passes on its priority
16438// updates to its stream request.
bncd16676a2016-07-20 16:23:0116439TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216441 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716442 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916443 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716444
krasinc06a72a2016-12-21 03:42:4616445 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116446 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716447
Ramin Halavatib5e433e62018-02-07 07:41:1016448 request.traffic_annotation =
16449 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16450
[email protected]bf828982013-08-14 18:01:4716451 TestCompletionCallback callback;
16452 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016453 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716454
16455 base::WeakPtr<FakeStreamRequest> fake_request =
16456 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216457 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716458 EXPECT_EQ(LOW, fake_request->priority());
16459
16460 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216461 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716462 EXPECT_EQ(LOWEST, fake_request->priority());
16463}
16464
[email protected]e86839fd2013-08-14 18:29:0316465// Make sure that HttpNetworkTransaction passes on its priority
16466// updates to its stream.
bncd16676a2016-07-20 16:23:0116467TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216469 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316470 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916471 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316472
krasinc06a72a2016-12-21 03:42:4616473 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116474 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316475
Ramin Halavatib5e433e62018-02-07 07:41:1016476 request.traffic_annotation =
16477 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16478
[email protected]e86839fd2013-08-14 18:29:0316479 TestCompletionCallback callback;
16480 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016481 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316482
16483 base::WeakPtr<FakeStreamRequest> fake_request =
16484 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216485 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316486 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216487 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316488 EXPECT_EQ(LOW, fake_stream->priority());
16489
16490 trans.SetPriority(LOWEST);
16491 EXPECT_EQ(LOWEST, fake_stream->priority());
16492}
16493
[email protected]043b68c82013-08-22 23:41:5216494// Tests that when a used socket is returned to the SSL socket pool, it's closed
16495// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116496TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216497 ClientSocketPoolManager::set_max_sockets_per_group(
16498 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16499 ClientSocketPoolManager::set_max_sockets_per_pool(
16500 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16501
16502 // Set up SSL request.
16503
16504 HttpRequestInfo ssl_request;
16505 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316506 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016507 ssl_request.traffic_annotation =
16508 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216509
16510 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316511 MockWrite(
16512 "GET / HTTP/1.1\r\n"
16513 "Host: www.example.org\r\n"
16514 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216515 };
16516 MockRead ssl_reads[] = {
16517 MockRead("HTTP/1.1 200 OK\r\n"),
16518 MockRead("Content-Length: 11\r\n\r\n"),
16519 MockRead("hello world"),
16520 MockRead(SYNCHRONOUS, OK),
16521 };
16522 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16523 ssl_writes, arraysize(ssl_writes));
16524 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16525
16526 SSLSocketDataProvider ssl(ASYNC, OK);
16527 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16528
16529 // Set up HTTP request.
16530
16531 HttpRequestInfo http_request;
16532 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316533 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016534 http_request.traffic_annotation =
16535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216536
16537 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316538 MockWrite(
16539 "GET / HTTP/1.1\r\n"
16540 "Host: www.example.org\r\n"
16541 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216542 };
16543 MockRead http_reads[] = {
16544 MockRead("HTTP/1.1 200 OK\r\n"),
16545 MockRead("Content-Length: 7\r\n\r\n"),
16546 MockRead("falafel"),
16547 MockRead(SYNCHRONOUS, OK),
16548 };
16549 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16550 http_writes, arraysize(http_writes));
16551 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16552
danakj1fd259a02016-04-16 03:17:0916553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216554
16555 // Start the SSL request.
16556 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616557 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016558 ASSERT_EQ(ERR_IO_PENDING,
16559 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16560 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216561
16562 // Start the HTTP request. Pool should stall.
16563 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616564 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016565 ASSERT_EQ(ERR_IO_PENDING,
16566 http_trans.Start(&http_request, http_callback.callback(),
16567 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116568 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216569
16570 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116571 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216572 std::string response_data;
bnc691fda62016-08-12 00:43:1616573 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216574 EXPECT_EQ("hello world", response_data);
16575
16576 // The SSL socket should automatically be closed, so the HTTP request can
16577 // start.
dcheng48459ac22014-08-26 00:46:4116578 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16579 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216580
16581 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116582 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616583 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216584 EXPECT_EQ("falafel", response_data);
16585
dcheng48459ac22014-08-26 00:46:4116586 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216587}
16588
16589// Tests that when a SSL connection is established but there's no corresponding
16590// request that needs it, the new socket is closed if the transport socket pool
16591// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116592TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216593 ClientSocketPoolManager::set_max_sockets_per_group(
16594 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16595 ClientSocketPoolManager::set_max_sockets_per_pool(
16596 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16597
16598 // Set up an ssl request.
16599
16600 HttpRequestInfo ssl_request;
16601 ssl_request.method = "GET";
16602 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1016603 ssl_request.traffic_annotation =
16604 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216605
16606 // No data will be sent on the SSL socket.
16607 StaticSocketDataProvider ssl_data;
16608 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16609
16610 SSLSocketDataProvider ssl(ASYNC, OK);
16611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16612
16613 // Set up HTTP request.
16614
16615 HttpRequestInfo http_request;
16616 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316617 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016618 http_request.traffic_annotation =
16619 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216620
16621 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316622 MockWrite(
16623 "GET / HTTP/1.1\r\n"
16624 "Host: www.example.org\r\n"
16625 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216626 };
16627 MockRead http_reads[] = {
16628 MockRead("HTTP/1.1 200 OK\r\n"),
16629 MockRead("Content-Length: 7\r\n\r\n"),
16630 MockRead("falafel"),
16631 MockRead(SYNCHRONOUS, OK),
16632 };
16633 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16634 http_writes, arraysize(http_writes));
16635 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16636
danakj1fd259a02016-04-16 03:17:0916637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216638
16639 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16640 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916641 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916642 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116643 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216644
16645 // Start the HTTP request. Pool should stall.
16646 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616647 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016648 ASSERT_EQ(ERR_IO_PENDING,
16649 http_trans.Start(&http_request, http_callback.callback(),
16650 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116651 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216652
16653 // The SSL connection will automatically be closed once the connection is
16654 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116655 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216656 std::string response_data;
bnc691fda62016-08-12 00:43:1616657 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216658 EXPECT_EQ("falafel", response_data);
16659
dcheng48459ac22014-08-26 00:46:4116660 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216661}
16662
bncd16676a2016-07-20 16:23:0116663TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916664 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216665 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916666 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216667 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416668
16669 HttpRequestInfo request;
16670 request.method = "POST";
16671 request.url = GURL("http://www.foo.com/");
16672 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016673 request.traffic_annotation =
16674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416675
danakj1fd259a02016-04-16 03:17:0916676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416678 // Send headers successfully, but get an error while sending the body.
16679 MockWrite data_writes[] = {
16680 MockWrite("POST / HTTP/1.1\r\n"
16681 "Host: www.foo.com\r\n"
16682 "Connection: keep-alive\r\n"
16683 "Content-Length: 3\r\n\r\n"),
16684 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16685 };
16686
16687 MockRead data_reads[] = {
16688 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16689 MockRead("hello world"),
16690 MockRead(SYNCHRONOUS, OK),
16691 };
16692 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16693 arraysize(data_writes));
16694 session_deps_.socket_factory->AddSocketDataProvider(&data);
16695
16696 TestCompletionCallback callback;
16697
tfarina42834112016-09-22 13:38:2016698 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416700
16701 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116702 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416703
bnc691fda62016-08-12 00:43:1616704 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216705 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416706
wezca1070932016-05-26 20:30:5216707 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416708 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16709
16710 std::string response_data;
bnc691fda62016-08-12 00:43:1616711 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116712 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416713 EXPECT_EQ("hello world", response_data);
16714}
16715
16716// This test makes sure the retry logic doesn't trigger when reading an error
16717// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116718TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416719 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416721 MockWrite data_writes[] = {
16722 MockWrite("GET / HTTP/1.1\r\n"
16723 "Host: www.foo.com\r\n"
16724 "Connection: keep-alive\r\n\r\n"),
16725 MockWrite("POST / HTTP/1.1\r\n"
16726 "Host: www.foo.com\r\n"
16727 "Connection: keep-alive\r\n"
16728 "Content-Length: 3\r\n\r\n"),
16729 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16730 };
16731
16732 MockRead data_reads[] = {
16733 MockRead("HTTP/1.1 200 Peachy\r\n"
16734 "Content-Length: 14\r\n\r\n"),
16735 MockRead("first response"),
16736 MockRead("HTTP/1.1 400 Not OK\r\n"
16737 "Content-Length: 15\r\n\r\n"),
16738 MockRead("second response"),
16739 MockRead(SYNCHRONOUS, OK),
16740 };
16741 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16742 arraysize(data_writes));
16743 session_deps_.socket_factory->AddSocketDataProvider(&data);
16744
16745 TestCompletionCallback callback;
16746 HttpRequestInfo request1;
16747 request1.method = "GET";
16748 request1.url = GURL("http://www.foo.com/");
16749 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016750 request1.traffic_annotation =
16751 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416752
bnc87dcefc2017-05-25 12:47:5816753 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916754 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016755 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416757
16758 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116759 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416760
16761 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216762 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416763
wezca1070932016-05-26 20:30:5216764 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416765 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16766
16767 std::string response_data1;
16768 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116769 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416770 EXPECT_EQ("first response", response_data1);
16771 // Delete the transaction to release the socket back into the socket pool.
16772 trans1.reset();
16773
danakj1fd259a02016-04-16 03:17:0916774 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216775 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916776 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216777 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416778
16779 HttpRequestInfo request2;
16780 request2.method = "POST";
16781 request2.url = GURL("http://www.foo.com/");
16782 request2.upload_data_stream = &upload_data_stream;
16783 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016784 request2.traffic_annotation =
16785 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416786
bnc691fda62016-08-12 00:43:1616787 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016788 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416790
16791 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116792 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416793
bnc691fda62016-08-12 00:43:1616794 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216795 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416796
wezca1070932016-05-26 20:30:5216797 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416798 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16799
16800 std::string response_data2;
bnc691fda62016-08-12 00:43:1616801 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116802 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416803 EXPECT_EQ("second response", response_data2);
16804}
16805
bncd16676a2016-07-20 16:23:0116806TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416807 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916808 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216809 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916810 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216811 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416812
16813 HttpRequestInfo request;
16814 request.method = "POST";
16815 request.url = GURL("http://www.foo.com/");
16816 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016817 request.traffic_annotation =
16818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416819
danakj1fd259a02016-04-16 03:17:0916820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416822 // Send headers successfully, but get an error while sending the body.
16823 MockWrite data_writes[] = {
16824 MockWrite("POST / HTTP/1.1\r\n"
16825 "Host: www.foo.com\r\n"
16826 "Connection: keep-alive\r\n"
16827 "Content-Length: 3\r\n\r\n"
16828 "fo"),
16829 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16830 };
16831
16832 MockRead data_reads[] = {
16833 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16834 MockRead("hello world"),
16835 MockRead(SYNCHRONOUS, OK),
16836 };
16837 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16838 arraysize(data_writes));
16839 session_deps_.socket_factory->AddSocketDataProvider(&data);
16840
16841 TestCompletionCallback callback;
16842
tfarina42834112016-09-22 13:38:2016843 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416845
16846 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116847 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416848
bnc691fda62016-08-12 00:43:1616849 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216850 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416851
wezca1070932016-05-26 20:30:5216852 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416853 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16854
16855 std::string response_data;
bnc691fda62016-08-12 00:43:1616856 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116857 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416858 EXPECT_EQ("hello world", response_data);
16859}
16860
16861// This tests the more common case than the previous test, where headers and
16862// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116863TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716864 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416865
16866 HttpRequestInfo request;
16867 request.method = "POST";
16868 request.url = GURL("http://www.foo.com/");
16869 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016870 request.traffic_annotation =
16871 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416872
danakj1fd259a02016-04-16 03:17:0916873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416875 // Send headers successfully, but get an error while sending the body.
16876 MockWrite data_writes[] = {
16877 MockWrite("POST / HTTP/1.1\r\n"
16878 "Host: www.foo.com\r\n"
16879 "Connection: keep-alive\r\n"
16880 "Transfer-Encoding: chunked\r\n\r\n"),
16881 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16882 };
16883
16884 MockRead data_reads[] = {
16885 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16886 MockRead("hello world"),
16887 MockRead(SYNCHRONOUS, OK),
16888 };
16889 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16890 arraysize(data_writes));
16891 session_deps_.socket_factory->AddSocketDataProvider(&data);
16892
16893 TestCompletionCallback callback;
16894
tfarina42834112016-09-22 13:38:2016895 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416897 // Make sure the headers are sent before adding a chunk. This ensures that
16898 // they can't be merged with the body in a single send. Not currently
16899 // necessary since a chunked body is never merged with headers, but this makes
16900 // the test more future proof.
16901 base::RunLoop().RunUntilIdle();
16902
mmenkecbc2b712014-10-09 20:29:0716903 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416904
16905 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116906 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416907
bnc691fda62016-08-12 00:43:1616908 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216909 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416910
wezca1070932016-05-26 20:30:5216911 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416912 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16913
16914 std::string response_data;
bnc691fda62016-08-12 00:43:1616915 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116916 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416917 EXPECT_EQ("hello world", response_data);
16918}
16919
bncd16676a2016-07-20 16:23:0116920TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916921 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216922 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916923 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216924 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416925
16926 HttpRequestInfo request;
16927 request.method = "POST";
16928 request.url = GURL("http://www.foo.com/");
16929 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016930 request.traffic_annotation =
16931 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416932
danakj1fd259a02016-04-16 03:17:0916933 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616934 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416935
16936 MockWrite data_writes[] = {
16937 MockWrite("POST / HTTP/1.1\r\n"
16938 "Host: www.foo.com\r\n"
16939 "Connection: keep-alive\r\n"
16940 "Content-Length: 3\r\n\r\n"),
16941 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16942 };
16943
16944 MockRead data_reads[] = {
16945 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16946 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16947 MockRead("hello world"),
16948 MockRead(SYNCHRONOUS, OK),
16949 };
16950 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16951 arraysize(data_writes));
16952 session_deps_.socket_factory->AddSocketDataProvider(&data);
16953
16954 TestCompletionCallback callback;
16955
tfarina42834112016-09-22 13:38:2016956 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416958
16959 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116960 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416961
bnc691fda62016-08-12 00:43:1616962 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216963 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416964
wezca1070932016-05-26 20:30:5216965 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416966 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16967
16968 std::string response_data;
bnc691fda62016-08-12 00:43:1616969 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116970 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416971 EXPECT_EQ("hello world", response_data);
16972}
16973
bncd16676a2016-07-20 16:23:0116974TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916975 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216976 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916977 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216978 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416979
16980 HttpRequestInfo request;
16981 request.method = "POST";
16982 request.url = GURL("http://www.foo.com/");
16983 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016984 request.traffic_annotation =
16985 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416986
danakj1fd259a02016-04-16 03:17:0916987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416989 // Send headers successfully, but get an error while sending the body.
16990 MockWrite data_writes[] = {
16991 MockWrite("POST / HTTP/1.1\r\n"
16992 "Host: www.foo.com\r\n"
16993 "Connection: keep-alive\r\n"
16994 "Content-Length: 3\r\n\r\n"),
16995 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16996 };
16997
16998 MockRead data_reads[] = {
16999 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17000 MockRead("hello world"),
17001 MockRead(SYNCHRONOUS, OK),
17002 };
17003 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17004 arraysize(data_writes));
17005 session_deps_.socket_factory->AddSocketDataProvider(&data);
17006
17007 TestCompletionCallback callback;
17008
tfarina42834112016-09-22 13:38:2017009 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417011
17012 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117013 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417014}
17015
bncd16676a2016-07-20 16:23:0117016TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417017 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917018 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217019 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917020 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217021 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417022
17023 HttpRequestInfo request;
17024 request.method = "POST";
17025 request.url = GURL("http://www.foo.com/");
17026 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017027 request.traffic_annotation =
17028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417029
danakj1fd259a02016-04-16 03:17:0917030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417032 // Send headers successfully, but get an error while sending the body.
17033 MockWrite data_writes[] = {
17034 MockWrite("POST / HTTP/1.1\r\n"
17035 "Host: www.foo.com\r\n"
17036 "Connection: keep-alive\r\n"
17037 "Content-Length: 3\r\n\r\n"),
17038 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17039 };
17040
17041 MockRead data_reads[] = {
17042 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17043 MockRead("HTTP/1.0 302 Redirect\r\n"),
17044 MockRead("Location: http://somewhere-else.com/\r\n"),
17045 MockRead("Content-Length: 0\r\n\r\n"),
17046 MockRead(SYNCHRONOUS, OK),
17047 };
17048 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17049 arraysize(data_writes));
17050 session_deps_.socket_factory->AddSocketDataProvider(&data);
17051
17052 TestCompletionCallback callback;
17053
tfarina42834112016-09-22 13:38:2017054 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417056
17057 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117058 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417059}
17060
bncd16676a2016-07-20 16:23:0117061TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917062 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217063 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917064 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217065 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417066
17067 HttpRequestInfo request;
17068 request.method = "POST";
17069 request.url = GURL("http://www.foo.com/");
17070 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017071 request.traffic_annotation =
17072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417073
danakj1fd259a02016-04-16 03:17:0917074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417076 // Send headers successfully, but get an error while sending the body.
17077 MockWrite data_writes[] = {
17078 MockWrite("POST / HTTP/1.1\r\n"
17079 "Host: www.foo.com\r\n"
17080 "Connection: keep-alive\r\n"
17081 "Content-Length: 3\r\n\r\n"),
17082 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17083 };
17084
17085 MockRead data_reads[] = {
17086 MockRead("HTTP 0.9 rocks!"),
17087 MockRead(SYNCHRONOUS, OK),
17088 };
17089 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17090 arraysize(data_writes));
17091 session_deps_.socket_factory->AddSocketDataProvider(&data);
17092
17093 TestCompletionCallback callback;
17094
tfarina42834112016-09-22 13:38:2017095 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417097
17098 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117099 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417100}
17101
bncd16676a2016-07-20 16:23:0117102TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917103 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217104 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917105 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217106 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417107
17108 HttpRequestInfo request;
17109 request.method = "POST";
17110 request.url = GURL("http://www.foo.com/");
17111 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017112 request.traffic_annotation =
17113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417114
danakj1fd259a02016-04-16 03:17:0917115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417117 // Send headers successfully, but get an error while sending the body.
17118 MockWrite data_writes[] = {
17119 MockWrite("POST / HTTP/1.1\r\n"
17120 "Host: www.foo.com\r\n"
17121 "Connection: keep-alive\r\n"
17122 "Content-Length: 3\r\n\r\n"),
17123 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17124 };
17125
17126 MockRead data_reads[] = {
17127 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17128 MockRead(SYNCHRONOUS, OK),
17129 };
17130 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17131 arraysize(data_writes));
17132 session_deps_.socket_factory->AddSocketDataProvider(&data);
17133
17134 TestCompletionCallback callback;
17135
tfarina42834112016-09-22 13:38:2017136 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117137 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417138
17139 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117140 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417141}
17142
Bence Békydca6bd92018-01-30 13:43:0617143#if BUILDFLAG(ENABLE_WEBSOCKETS)
17144
17145namespace {
17146
17147void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17148 headers->SetHeader("Connection", "Upgrade");
17149 headers->SetHeader("Upgrade", "websocket");
17150 headers->SetHeader("Origin", "http://www.example.org");
17151 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617152}
17153
17154} // namespace
17155
17156TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
17157 // The same logic needs to be tested for both ws: and wss: schemes, but this
17158 // test is already parameterised on NextProto, so it uses a loop to verify
17159 // that the different schemes work.
17160 std::string test_cases[] = {"ws://www.example.org/",
17161 "wss://www.example.org/"};
17162 for (size_t i = 0; i < arraysize(test_cases); ++i) {
17163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17164 HttpNetworkSessionPeer peer(session.get());
17165 FakeStreamFactory* fake_factory = new FakeStreamFactory();
17166 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
17167
17168 HttpRequestInfo request;
17169 request.method = "GET";
17170 request.url = GURL(test_cases[i]);
Ramin Halavatib5e433e62018-02-07 07:41:1017171 request.traffic_annotation =
17172 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617173
Bence Béky8d1c6052018-02-07 12:48:1517174 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17175
Bence Békydca6bd92018-01-30 13:43:0617176 HttpNetworkTransaction trans(LOW, session.get());
17177 trans.SetWebSocketHandshakeStreamCreateHelper(
17178 &websocket_stream_create_helper);
17179
17180 TestCompletionCallback callback;
17181 EXPECT_EQ(ERR_IO_PENDING,
17182 trans.Start(&request, callback.callback(), NetLogWithSource()));
17183
17184 base::WeakPtr<FakeStreamRequest> fake_request =
17185 fake_factory->last_stream_request();
17186 ASSERT_TRUE(fake_request);
17187 EXPECT_EQ(&websocket_stream_create_helper,
17188 fake_request->websocket_stream_create_helper());
17189 }
17190}
17191
Adam Rice425cf122015-01-19 06:18:2417192// Verify that proxy headers are not sent to the destination server when
17193// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117194TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417195 HttpRequestInfo request;
17196 request.method = "GET";
bncce36dca22015-04-21 22:11:2317197 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017198 request.traffic_annotation =
17199 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417200 AddWebSocketHeaders(&request.extra_headers);
17201
17202 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917203 session_deps_.proxy_resolution_service =
17204 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2417205
danakj1fd259a02016-04-16 03:17:0917206 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417207
17208 // Since a proxy is configured, try to establish a tunnel.
17209 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717210 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17211 "Host: www.example.org:443\r\n"
17212 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417213
17214 // After calling trans->RestartWithAuth(), this is the request we should
17215 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717216 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17217 "Host: www.example.org:443\r\n"
17218 "Proxy-Connection: keep-alive\r\n"
17219 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417220
rsleevidb16bb02015-11-12 23:47:1717221 MockWrite("GET / HTTP/1.1\r\n"
17222 "Host: www.example.org\r\n"
17223 "Connection: Upgrade\r\n"
17224 "Upgrade: websocket\r\n"
17225 "Origin: http://www.example.org\r\n"
17226 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517227 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17228 "Sec-WebSocket-Extensions: permessage-deflate; "
17229 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417230
17231 // The proxy responds to the connect with a 407, using a persistent
17232 // connection.
17233 MockRead data_reads[] = {
17234 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517235 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17236 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17237 "Content-Length: 0\r\n"
17238 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417239
17240 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17241
Bence Béky8d1c6052018-02-07 12:48:1517242 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17243 "Upgrade: websocket\r\n"
17244 "Connection: Upgrade\r\n"
17245 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417246
17247 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17248 arraysize(data_writes));
17249 session_deps_.socket_factory->AddSocketDataProvider(&data);
17250 SSLSocketDataProvider ssl(ASYNC, OK);
17251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17252
Bence Béky8d1c6052018-02-07 12:48:1517253 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17254
bnc87dcefc2017-05-25 12:47:5817255 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917256 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417257 trans->SetWebSocketHandshakeStreamCreateHelper(
17258 &websocket_stream_create_helper);
17259
17260 {
17261 TestCompletionCallback callback;
17262
tfarina42834112016-09-22 13:38:2017263 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417265
17266 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117267 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417268 }
17269
17270 const HttpResponseInfo* response = trans->GetResponseInfo();
17271 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217272 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417273 EXPECT_EQ(407, response->headers->response_code());
17274
17275 {
17276 TestCompletionCallback callback;
17277
17278 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17279 callback.callback());
robpercival214763f2016-07-01 23:27:0117280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417281
17282 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117283 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417284 }
17285
17286 response = trans->GetResponseInfo();
17287 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217288 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417289
17290 EXPECT_EQ(101, response->headers->response_code());
17291
17292 trans.reset();
17293 session->CloseAllConnections();
17294}
17295
17296// Verify that proxy headers are not sent to the destination server when
17297// establishing a tunnel for an insecure WebSocket connection.
17298// This requires the authentication info to be injected into the auth cache
17299// due to crbug.com/395064
17300// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117301TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417302 HttpRequestInfo request;
17303 request.method = "GET";
bncce36dca22015-04-21 22:11:2317304 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017305 request.traffic_annotation =
17306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417307 AddWebSocketHeaders(&request.extra_headers);
17308
17309 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917310 session_deps_.proxy_resolution_service =
17311 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2417312
danakj1fd259a02016-04-16 03:17:0917313 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417314
17315 MockWrite data_writes[] = {
17316 // Try to establish a tunnel for the WebSocket connection, with
17317 // credentials. Because WebSockets have a separate set of socket pools,
17318 // they cannot and will not use the same TCP/IP connection as the
17319 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517320 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17321 "Host: www.example.org:80\r\n"
17322 "Proxy-Connection: keep-alive\r\n"
17323 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417324
Bence Béky8d1c6052018-02-07 12:48:1517325 MockWrite("GET / HTTP/1.1\r\n"
17326 "Host: www.example.org\r\n"
17327 "Connection: Upgrade\r\n"
17328 "Upgrade: websocket\r\n"
17329 "Origin: http://www.example.org\r\n"
17330 "Sec-WebSocket-Version: 13\r\n"
17331 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17332 "Sec-WebSocket-Extensions: permessage-deflate; "
17333 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417334
17335 MockRead data_reads[] = {
17336 // HTTP CONNECT with credentials.
17337 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17338
17339 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517340 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17341 "Upgrade: websocket\r\n"
17342 "Connection: Upgrade\r\n"
17343 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417344
17345 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17346 arraysize(data_writes));
17347 session_deps_.socket_factory->AddSocketDataProvider(&data);
17348
17349 session->http_auth_cache()->Add(
17350 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17351 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17352
Bence Béky8d1c6052018-02-07 12:48:1517353 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17354
bnc87dcefc2017-05-25 12:47:5817355 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917356 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417357 trans->SetWebSocketHandshakeStreamCreateHelper(
17358 &websocket_stream_create_helper);
17359
17360 TestCompletionCallback callback;
17361
tfarina42834112016-09-22 13:38:2017362 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417364
17365 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117366 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417367
17368 const HttpResponseInfo* response = trans->GetResponseInfo();
17369 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217370 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417371
17372 EXPECT_EQ(101, response->headers->response_code());
17373
17374 trans.reset();
17375 session->CloseAllConnections();
17376}
17377
Bence Békydca6bd92018-01-30 13:43:0617378#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17379
bncd16676a2016-07-20 16:23:0117380TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917381 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217382 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917383 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217384 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217385
17386 HttpRequestInfo request;
17387 request.method = "POST";
17388 request.url = GURL("http://www.foo.com/");
17389 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017390 request.traffic_annotation =
17391 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217392
danakj1fd259a02016-04-16 03:17:0917393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217395 MockWrite data_writes[] = {
17396 MockWrite("POST / HTTP/1.1\r\n"
17397 "Host: www.foo.com\r\n"
17398 "Connection: keep-alive\r\n"
17399 "Content-Length: 3\r\n\r\n"),
17400 MockWrite("foo"),
17401 };
17402
17403 MockRead data_reads[] = {
17404 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17405 MockRead(SYNCHRONOUS, OK),
17406 };
17407 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17408 arraysize(data_writes));
17409 session_deps_.socket_factory->AddSocketDataProvider(&data);
17410
17411 TestCompletionCallback callback;
17412
17413 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017414 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117415 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217416
17417 std::string response_data;
bnc691fda62016-08-12 00:43:1617418 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217419
17420 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617421 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217422 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617423 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217424}
17425
bncd16676a2016-07-20 16:23:0117426TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917427 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217428 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917429 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217430 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217431
17432 HttpRequestInfo request;
17433 request.method = "POST";
17434 request.url = GURL("http://www.foo.com/");
17435 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017436 request.traffic_annotation =
17437 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217438
danakj1fd259a02016-04-16 03:17:0917439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217441 MockWrite data_writes[] = {
17442 MockWrite("POST / HTTP/1.1\r\n"
17443 "Host: www.foo.com\r\n"
17444 "Connection: keep-alive\r\n"
17445 "Content-Length: 3\r\n\r\n"),
17446 MockWrite("foo"),
17447 };
17448
17449 MockRead data_reads[] = {
17450 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17451 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17452 MockRead(SYNCHRONOUS, OK),
17453 };
17454 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17455 arraysize(data_writes));
17456 session_deps_.socket_factory->AddSocketDataProvider(&data);
17457
17458 TestCompletionCallback callback;
17459
17460 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017461 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117462 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217463
17464 std::string response_data;
bnc691fda62016-08-12 00:43:1617465 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217466
17467 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617468 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217469 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617470 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217471}
17472
bncd16676a2016-07-20 16:23:0117473TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217474 ChunkedUploadDataStream upload_data_stream(0);
17475
17476 HttpRequestInfo request;
17477 request.method = "POST";
17478 request.url = GURL("http://www.foo.com/");
17479 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017480 request.traffic_annotation =
17481 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217482
danakj1fd259a02016-04-16 03:17:0917483 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617484 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217485 // Send headers successfully, but get an error while sending the body.
17486 MockWrite data_writes[] = {
17487 MockWrite("POST / HTTP/1.1\r\n"
17488 "Host: www.foo.com\r\n"
17489 "Connection: keep-alive\r\n"
17490 "Transfer-Encoding: chunked\r\n\r\n"),
17491 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17492 };
17493
17494 MockRead data_reads[] = {
17495 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17496 MockRead(SYNCHRONOUS, OK),
17497 };
17498 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17499 arraysize(data_writes));
17500 session_deps_.socket_factory->AddSocketDataProvider(&data);
17501
17502 TestCompletionCallback callback;
17503
17504 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017505 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217506
17507 base::RunLoop().RunUntilIdle();
17508 upload_data_stream.AppendData("f", 1, false);
17509
17510 base::RunLoop().RunUntilIdle();
17511 upload_data_stream.AppendData("oo", 2, true);
17512
robpercival214763f2016-07-01 23:27:0117513 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217514
17515 std::string response_data;
bnc691fda62016-08-12 00:43:1617516 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217517
17518 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617519 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217520 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617521 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217522}
17523
rdsmith1d343be52016-10-21 20:37:5017524// Confirm that transactions whose throttle is created in (and stays in)
17525// the unthrottled state are not blocked.
17526TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17527 TestNetworkStreamThrottler* throttler(nullptr);
17528 std::unique_ptr<HttpNetworkSession> session(
17529 CreateSessionWithThrottler(&session_deps_, &throttler));
17530
17531 // Send a simple request and make sure it goes through.
17532 HttpRequestInfo request;
17533 request.method = "GET";
17534 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017535 request.traffic_annotation =
17536 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017537
bnc87dcefc2017-05-25 12:47:5817538 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917539 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017540
17541 MockWrite data_writes[] = {
17542 MockWrite("GET / HTTP/1.1\r\n"
17543 "Host: www.example.org\r\n"
17544 "Connection: keep-alive\r\n\r\n"),
17545 };
17546 MockRead data_reads[] = {
17547 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17548 MockRead(SYNCHRONOUS, OK),
17549 };
17550 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17551 arraysize(data_writes));
17552 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17553
17554 TestCompletionCallback callback;
17555 trans->Start(&request, callback.callback(), NetLogWithSource());
17556 EXPECT_EQ(OK, callback.WaitForResult());
17557}
17558
17559// Confirm requests can be blocked by a throttler, and are resumed
17560// when the throttle is unblocked.
17561TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17562 TestNetworkStreamThrottler* throttler(nullptr);
17563 std::unique_ptr<HttpNetworkSession> session(
17564 CreateSessionWithThrottler(&session_deps_, &throttler));
17565
17566 // Send a simple request and make sure it goes through.
17567 HttpRequestInfo request;
17568 request.method = "GET";
17569 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017570 request.traffic_annotation =
17571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017572
17573 MockWrite data_writes[] = {
17574 MockWrite("GET / HTTP/1.1\r\n"
17575 "Host: www.example.org\r\n"
17576 "Connection: keep-alive\r\n\r\n"),
17577 };
17578 MockRead data_reads[] = {
17579 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17580 MockRead(SYNCHRONOUS, OK),
17581 };
17582 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17583 arraysize(data_writes));
17584 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17585
17586 // Start a request that will be throttled at start; confirm it
17587 // doesn't complete.
17588 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817589 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917590 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017591
17592 TestCompletionCallback callback;
17593 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17594 EXPECT_EQ(ERR_IO_PENDING, rv);
17595
17596 base::RunLoop().RunUntilIdle();
17597 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17598 EXPECT_FALSE(callback.have_result());
17599
17600 // Confirm the request goes on to complete when unthrottled.
17601 throttler->UnthrottleAllRequests();
17602 base::RunLoop().RunUntilIdle();
17603 ASSERT_TRUE(callback.have_result());
17604 EXPECT_EQ(OK, callback.WaitForResult());
17605}
17606
17607// Destroy a request while it's throttled.
17608TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17609 TestNetworkStreamThrottler* throttler(nullptr);
17610 std::unique_ptr<HttpNetworkSession> session(
17611 CreateSessionWithThrottler(&session_deps_, &throttler));
17612
17613 // Send a simple request and make sure it goes through.
17614 HttpRequestInfo request;
17615 request.method = "GET";
17616 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017617 request.traffic_annotation =
17618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017619
17620 MockWrite data_writes[] = {
17621 MockWrite("GET / HTTP/1.1\r\n"
17622 "Host: www.example.org\r\n"
17623 "Connection: keep-alive\r\n\r\n"),
17624 };
17625 MockRead data_reads[] = {
17626 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17627 MockRead(SYNCHRONOUS, OK),
17628 };
17629 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17630 arraysize(data_writes));
17631 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17632
17633 // Start a request that will be throttled at start; confirm it
17634 // doesn't complete.
17635 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817636 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917637 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017638
17639 TestCompletionCallback callback;
17640 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17641 EXPECT_EQ(ERR_IO_PENDING, rv);
17642
17643 base::RunLoop().RunUntilIdle();
17644 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17645 EXPECT_FALSE(callback.have_result());
17646
17647 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17648 trans.reset();
17649 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17650}
17651
17652// Confirm the throttler receives SetPriority calls.
17653TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17654 TestNetworkStreamThrottler* throttler(nullptr);
17655 std::unique_ptr<HttpNetworkSession> session(
17656 CreateSessionWithThrottler(&session_deps_, &throttler));
17657
17658 // Send a simple request and make sure it goes through.
17659 HttpRequestInfo request;
17660 request.method = "GET";
17661 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017662 request.traffic_annotation =
17663 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017664
17665 MockWrite data_writes[] = {
17666 MockWrite("GET / HTTP/1.1\r\n"
17667 "Host: www.example.org\r\n"
17668 "Connection: keep-alive\r\n\r\n"),
17669 };
17670 MockRead data_reads[] = {
17671 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17672 MockRead(SYNCHRONOUS, OK),
17673 };
17674 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17675 arraysize(data_writes));
17676 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17677
17678 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917679 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017680 // Start the transaction to associate a throttle with it.
17681 TestCompletionCallback callback;
17682 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17683 EXPECT_EQ(ERR_IO_PENDING, rv);
17684
17685 EXPECT_EQ(0, throttler->num_set_priority_calls());
17686 trans->SetPriority(LOW);
17687 EXPECT_EQ(1, throttler->num_set_priority_calls());
17688 EXPECT_EQ(LOW, throttler->last_priority_set());
17689
17690 throttler->UnthrottleAllRequests();
17691 base::RunLoop().RunUntilIdle();
17692 ASSERT_TRUE(callback.have_result());
17693 EXPECT_EQ(OK, callback.WaitForResult());
17694}
17695
17696// Confirm that unthrottling from a SetPriority call by the
17697// throttler works properly.
17698TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17699 TestNetworkStreamThrottler* throttler(nullptr);
17700 std::unique_ptr<HttpNetworkSession> session(
17701 CreateSessionWithThrottler(&session_deps_, &throttler));
17702
17703 // Send a simple request and make sure it goes through.
17704 HttpRequestInfo request;
17705 request.method = "GET";
17706 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017707 request.traffic_annotation =
17708 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017709
17710 MockWrite data_writes[] = {
17711 MockWrite("GET / HTTP/1.1\r\n"
17712 "Host: www.example.org\r\n"
17713 "Connection: keep-alive\r\n\r\n"),
17714 };
17715 MockRead data_reads[] = {
17716 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17717 MockRead(SYNCHRONOUS, OK),
17718 };
17719 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17720 arraysize(data_writes));
17721 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17722
17723 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17724 data_writes, arraysize(data_writes));
17725 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17726
17727 // Start a request that will be throttled at start; confirm it
17728 // doesn't complete.
17729 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817730 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917731 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017732
17733 TestCompletionCallback callback;
17734 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17735 EXPECT_EQ(ERR_IO_PENDING, rv);
17736
17737 base::RunLoop().RunUntilIdle();
17738 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17739 EXPECT_FALSE(callback.have_result());
17740
17741 // Create a new request, call SetPriority on it to unthrottle,
17742 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917743 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017744 throttler->set_priority_change_closure(
17745 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17746 base::Unretained(throttler)));
17747
17748 // Start the transaction to associate a throttle with it.
17749 TestCompletionCallback callback1;
17750 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17751 EXPECT_EQ(ERR_IO_PENDING, rv);
17752
17753 trans1->SetPriority(IDLE);
17754
17755 base::RunLoop().RunUntilIdle();
17756 ASSERT_TRUE(callback.have_result());
17757 EXPECT_EQ(OK, callback.WaitForResult());
17758 ASSERT_TRUE(callback1.have_result());
17759 EXPECT_EQ(OK, callback1.WaitForResult());
17760}
17761
17762// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817763void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017764
17765// Confirm that destroying a transaction from a SetPriority call by the
17766// throttler works properly.
17767TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17768 TestNetworkStreamThrottler* throttler(nullptr);
17769 std::unique_ptr<HttpNetworkSession> session(
17770 CreateSessionWithThrottler(&session_deps_, &throttler));
17771
17772 // Send a simple request and make sure it goes through.
17773 HttpRequestInfo request;
17774 request.method = "GET";
17775 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017776 request.traffic_annotation =
17777 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017778
17779 MockWrite data_writes[] = {
17780 MockWrite("GET / HTTP/1.1\r\n"
17781 "Host: www.example.org\r\n"
17782 "Connection: keep-alive\r\n\r\n"),
17783 };
17784 MockRead data_reads[] = {
17785 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17786 MockRead(SYNCHRONOUS, OK),
17787 };
17788 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17789 arraysize(data_writes));
17790 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17791
17792 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17793 data_writes, arraysize(data_writes));
17794 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17795
17796 // Start a request that will be throttled at start; confirm it
17797 // doesn't complete.
17798 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817799 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917800 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017801
17802 TestCompletionCallback callback;
17803 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17804 EXPECT_EQ(ERR_IO_PENDING, rv);
17805
17806 base::RunLoop().RunUntilIdle();
17807 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17808 EXPECT_FALSE(callback.have_result());
17809
17810 // Arrange for the set priority call on the above transaction to delete
17811 // the transaction.
bnc87dcefc2017-05-25 12:47:5817812 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017813 throttler->set_priority_change_closure(
17814 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17815
17816 // Call it and check results (partially a "doesn't crash" test).
17817 trans_ptr->SetPriority(IDLE);
17818 trans_ptr = nullptr; // No longer a valid pointer.
17819
17820 base::RunLoop().RunUntilIdle();
17821 ASSERT_FALSE(callback.have_result());
17822}
17823
nharperb7441ef2016-01-25 23:54:1417824#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117825TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417826 const std::string https_url = "https://www.example.com";
17827 HttpRequestInfo request;
17828 request.url = GURL(https_url);
17829 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:1017830 request.traffic_annotation =
17831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417832
17833 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917834 ssl.ssl_info.token_binding_negotiated = true;
17835 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617836 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17838
bnc42331402016-07-25 13:36:1517839 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117840 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17841 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417842 MockRead(ASYNC, ERR_IO_PENDING)};
17843 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17844 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817845 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917846 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417848
17849 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17850 TestCompletionCallback callback;
17851 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017852 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017853
17854 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417855
17856 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17857 HttpRequestHeaders headers;
17858 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17859 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17860}
17861#endif // !defined(OS_IOS)
17862
eustasc7d27da2017-04-06 10:33:2017863void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17864 const std::string& accept_encoding,
17865 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317866 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017867 bool should_match) {
17868 HttpRequestInfo request;
17869 request.method = "GET";
17870 request.url = GURL("http://www.foo.com/");
17871 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17872 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1017873 request.traffic_annotation =
17874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017875
17876 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17878 // Send headers successfully, but get an error while sending the body.
17879 MockWrite data_writes[] = {
17880 MockWrite("GET / HTTP/1.1\r\n"
17881 "Host: www.foo.com\r\n"
17882 "Connection: keep-alive\r\n"
17883 "Accept-Encoding: "),
17884 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17885 };
17886
sky50576f32017-05-01 19:28:0317887 std::string response_code = "200 OK";
17888 std::string extra;
17889 if (!location.empty()) {
17890 response_code = "301 Redirect\r\nLocation: ";
17891 response_code.append(location);
17892 }
17893
eustasc7d27da2017-04-06 10:33:2017894 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317895 MockRead("HTTP/1.0 "),
17896 MockRead(response_code.data()),
17897 MockRead("\r\nContent-Encoding: "),
17898 MockRead(content_encoding.data()),
17899 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017900 MockRead(SYNCHRONOUS, OK),
17901 };
17902 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17903 arraysize(data_writes));
17904 session_deps->socket_factory->AddSocketDataProvider(&data);
17905
17906 TestCompletionCallback callback;
17907
17908 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17910
17911 rv = callback.WaitForResult();
17912 if (should_match) {
17913 EXPECT_THAT(rv, IsOk());
17914 } else {
17915 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17916 }
17917}
17918
17919TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317920 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017921}
17922
17923TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317924 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17925 true);
eustasc7d27da2017-04-06 10:33:2017926}
17927
17928TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17929 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317930 "", false);
17931}
17932
17933TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17934 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17935 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017936}
17937
xunjieli96f2a402017-06-05 17:24:2717938TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17939 ProxyConfig proxy_config;
17940 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17941 proxy_config.set_pac_mandatory(true);
17942 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917943 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Jeremy Roman0579ed62017-08-29 15:56:1917944 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417945 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717946
17947 HttpRequestInfo request;
17948 request.method = "GET";
17949 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017950 request.traffic_annotation =
17951 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717952
17953 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17955
17956 TestCompletionCallback callback;
17957
17958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17960 EXPECT_THAT(callback.WaitForResult(),
17961 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17962}
17963
17964TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17965 ProxyConfig proxy_config;
17966 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17967 proxy_config.set_pac_mandatory(true);
17968 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17969 new MockAsyncProxyResolverFactory(false);
17970 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917971 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
17972 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
17973 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717974 HttpRequestInfo request;
17975 request.method = "GET";
17976 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017977 request.traffic_annotation =
17978 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717979
17980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17982
17983 TestCompletionCallback callback;
17984 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17986
17987 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17988 ERR_FAILED, &resolver);
17989 EXPECT_THAT(callback.WaitForResult(),
17990 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17991}
17992
17993TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917994 session_deps_.proxy_resolution_service =
17995 ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
xunjieli96f2a402017-06-05 17:24:2717996 session_deps_.enable_quic = false;
17997 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17998
17999 HttpRequestInfo request;
18000 request.method = "GET";
18001 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018002 request.traffic_annotation =
18003 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718004
18005 TestCompletionCallback callback;
18006 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18007 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18009
18010 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18011}
18012
[email protected]89ceba9a2009-03-21 03:46:0618013} // namespace net