blob: e7e1cd39627b6b763973e0d35264136912fa9e2f [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
[email protected]bb88e1d32013-05-03 23:11:07579 void CheckErrorIsPassedBack(int error, IoMode mode);
580
[email protected]4bd46222013-05-14 19:32:23581 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07582 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15583 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03584
585 // Original socket limits. Some tests set these. Safest to always restore
586 // them once each test has been run.
587 int old_max_group_sockets_;
588 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15589};
[email protected]231d5a32008-09-13 00:45:27590
[email protected]448d4ca52012-03-04 04:12:23591namespace {
592
ryansturm49a8cb12016-06-15 16:51:09593class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27594 public:
ryansturm49a8cb12016-06-15 16:51:09595 BeforeHeadersSentHandler()
596 : observed_before_headers_sent_with_proxy_(false),
597 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27598
ryansturm49a8cb12016-06-15 16:51:09599 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
600 HttpRequestHeaders* request_headers) {
601 observed_before_headers_sent_ = true;
602 if (!proxy_info.is_http() && !proxy_info.is_https() &&
603 !proxy_info.is_quic()) {
604 return;
605 }
606 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27607 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
608 }
609
ryansturm49a8cb12016-06-15 16:51:09610 bool observed_before_headers_sent_with_proxy() const {
611 return observed_before_headers_sent_with_proxy_;
612 }
613
614 bool observed_before_headers_sent() const {
615 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27616 }
617
618 std::string observed_proxy_server_uri() const {
619 return observed_proxy_server_uri_;
620 }
621
622 private:
ryansturm49a8cb12016-06-15 16:51:09623 bool observed_before_headers_sent_with_proxy_;
624 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27625 std::string observed_proxy_server_uri_;
626
ryansturm49a8cb12016-06-15 16:51:09627 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27628};
629
[email protected]15a5ccf82008-10-23 19:57:43630// Fill |str| with a long header list that consumes >= |size| bytes.
631void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51632 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19633 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
634 const int sizeof_row = strlen(row);
635 const int num_rows = static_cast<int>(
636 ceil(static_cast<float>(size) / sizeof_row));
637 const int sizeof_data = num_rows * sizeof_row;
638 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43639 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51640
[email protected]4ddaf2502008-10-23 18:26:19641 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43642 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19643}
644
thakis84dff942015-07-28 20:47:38645#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09646uint64_t MockGetMSTime() {
647 // Tue, 23 May 2017 20:13:07 +0000
648 return 131400439870000000;
649}
650
[email protected]385a4672009-03-11 22:21:29651// Alternative functions that eliminate randomness and dependency on the local
652// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37653void MockGenerateRandom(uint8_t* output, size_t n) {
654 // This is set to 0xaa because the client challenge for testing in
655 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
656 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29657}
658
[email protected]fe2bc6a2009-03-23 16:52:20659std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37660 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29661}
thakis84dff942015-07-28 20:47:38662#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29663
[email protected]e60e47a2010-07-14 03:37:18664template<typename ParentPool>
665class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31666 public:
[email protected]9e1bdd32011-02-03 21:48:34667 CaptureGroupNameSocketPool(HostResolver* host_resolver,
668 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18669
[email protected]d80a4322009-08-14 07:07:49670 const std::string last_group_name_received() const {
671 return last_group_name_;
672 }
673
Tarun Bansal162eabe52018-01-20 01:16:39674 bool socket_requested() const { return socket_requested_; }
675
dmichaeld6e570d2014-12-18 22:30:57676 int RequestSocket(const std::string& group_name,
677 const void* socket_params,
678 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54679 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15680 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57681 ClientSocketHandle* handle,
682 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20683 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31684 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39685 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31686 return ERR_IO_PENDING;
687 }
dmichaeld6e570d2014-12-18 22:30:57688 void CancelRequest(const std::string& group_name,
689 ClientSocketHandle* handle) override {}
690 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09691 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57692 int id) override {}
693 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23694 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57695 int IdleSocketCount() const override { return 0; }
696 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31697 return 0;
698 }
dmichaeld6e570d2014-12-18 22:30:57699 LoadState GetLoadState(const std::string& group_name,
700 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31701 return LOAD_STATE_IDLE;
702 }
dmichaeld6e570d2014-12-18 22:30:57703 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26704 return base::TimeDelta();
705 }
[email protected]d80a4322009-08-14 07:07:49706
707 private:
[email protected]04e5be32009-06-26 20:00:31708 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39709 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31710};
711
[email protected]ab739042011-04-07 15:22:28712typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
713CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13714typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
715CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06716typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11717CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18718typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
719CaptureGroupNameSSLSocketPool;
720
rkaplowd90695c2015-03-25 22:12:41721template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18722CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34723 HostResolver* host_resolver,
724 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21725 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18726
hashimoto0d3e4fb2015-01-09 05:02:50727template <>
[email protected]2df19bb2010-08-25 20:13:46728CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21729 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34730 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09731 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46732
[email protected]007b3f82013-04-09 08:46:45733template <>
[email protected]e60e47a2010-07-14 03:37:18734CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21735 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34736 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45737 : SSLClientSocketPool(0,
738 0,
[email protected]007b3f82013-04-09 08:46:45739 cert_verifier,
740 NULL,
741 NULL,
[email protected]284303b62013-11-28 15:11:54742 NULL,
eranm6571b2b2014-12-03 15:53:23743 NULL,
[email protected]007b3f82013-04-09 08:46:45744 std::string(),
745 NULL,
746 NULL,
747 NULL,
748 NULL,
749 NULL,
[email protected]8e458552014-08-05 00:02:15750 NULL) {
751}
[email protected]2227c692010-05-04 15:36:11752
[email protected]231d5a32008-09-13 00:45:27753//-----------------------------------------------------------------------------
754
[email protected]79cb5c12011-09-12 13:12:04755// Helper functions for validating that AuthChallengeInfo's are correctly
756// configured for common cases.
757bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
758 if (!auth_challenge)
759 return false;
760 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43761 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04762 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19763 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04764 return true;
765}
766
767bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
768 if (!auth_challenge)
769 return false;
770 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43771 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
772 EXPECT_EQ("MyRealm1", auth_challenge->realm);
773 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
774 return true;
775}
776
777bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
778 if (!auth_challenge)
779 return false;
780 EXPECT_TRUE(auth_challenge->is_proxy);
781 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04782 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19783 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04784 return true;
785}
786
787bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
788 if (!auth_challenge)
789 return false;
790 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43791 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04792 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19793 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04794 return true;
795}
796
thakis84dff942015-07-28 20:47:38797#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04798bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
799 if (!auth_challenge)
800 return false;
801 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55802 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04803 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19804 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04805 return true;
806}
thakis84dff942015-07-28 20:47:38807#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04808
[email protected]448d4ca52012-03-04 04:12:23809} // namespace
810
bncd16676a2016-07-20 16:23:01811TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27814}
815
bncd16676a2016-07-20 16:23:01816TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27817 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35818 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
819 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06820 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27821 };
[email protected]31a2bfe2010-02-09 08:03:39822 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
823 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01824 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27825 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
826 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22827 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
828 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47829 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59830
831 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27832}
833
834// Response with no status line.
bncd16676a2016-07-20 16:23:01835TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27836 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35837 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06838 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27839 };
[email protected]31a2bfe2010-02-09 08:03:39840 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
841 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41842 EXPECT_THAT(out.rv, IsOk());
843 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
844 EXPECT_EQ("hello world", out.response_data);
845 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
846 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27847}
848
mmenkea7da6da2016-09-01 21:56:52849// Response with no status line, and a weird port. Should fail by default.
850TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
851 MockRead data_reads[] = {
852 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
853 };
854
855 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
856 session_deps_.socket_factory->AddSocketDataProvider(&data);
857
858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
859
krasinc06a72a2016-12-21 03:42:46860 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58861 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19862 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52863
mmenkea7da6da2016-09-01 21:56:52864 request.method = "GET";
865 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10866 request.traffic_annotation =
867 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
868
mmenkea7da6da2016-09-01 21:56:52869 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20870 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52871 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
872}
873
Shivani Sharmafdcaefd2017-11-02 00:12:26874// Tests that request info can be destroyed after the headers phase is complete.
875TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
877 auto trans =
878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
879
880 MockRead data_reads[] = {
881 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
882 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
883 };
884 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
885 session_deps_.socket_factory->AddSocketDataProvider(&data);
886
887 TestCompletionCallback callback;
888
889 {
890 auto request = std::make_unique<HttpRequestInfo>();
891 request->method = "GET";
892 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10893 request->traffic_annotation =
894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26895
896 int rv =
897 trans->Start(request.get(), callback.callback(), NetLogWithSource());
898
899 EXPECT_THAT(callback.GetResult(rv), IsOk());
900 } // Let request info be destroyed.
901
902 trans.reset();
903}
904
mmenkea7da6da2016-09-01 21:56:52905// Response with no status line, and a weird port. Option to allow weird ports
906// enabled.
907TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
908 MockRead data_reads[] = {
909 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
910 };
911
912 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
913 session_deps_.socket_factory->AddSocketDataProvider(&data);
914 session_deps_.http_09_on_non_default_ports_enabled = true;
915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
916
krasinc06a72a2016-12-21 03:42:46917 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58918 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19919 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52920
mmenkea7da6da2016-09-01 21:56:52921 request.method = "GET";
922 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10923 request.traffic_annotation =
924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
925
mmenkea7da6da2016-09-01 21:56:52926 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20927 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52928 EXPECT_THAT(callback.GetResult(rv), IsOk());
929
930 const HttpResponseInfo* info = trans->GetResponseInfo();
931 ASSERT_TRUE(info->headers);
932 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
933
934 // Don't bother to read the body - that's verified elsewhere, important thing
935 // is that the option to allow HTTP/0.9 on non-default ports is respected.
936}
937
[email protected]231d5a32008-09-13 00:45:27938// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01939TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27940 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35941 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06942 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27943 };
[email protected]31a2bfe2010-02-09 08:03:39944 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
945 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01946 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27947 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
948 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22949 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
950 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27951}
952
953// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01954TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27955 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35956 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06957 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27958 };
[email protected]31a2bfe2010-02-09 08:03:39959 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
960 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01961 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27962 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
963 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22964 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
965 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27966}
967
968// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01969TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27970 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35971 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06972 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27973 };
[email protected]31a2bfe2010-02-09 08:03:39974 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
975 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41976 EXPECT_THAT(out.rv, IsOk());
977 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
978 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
979 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
980 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27981}
982
983// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01984TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27985 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35986 MockRead("\n"),
987 MockRead("\n"),
988 MockRead("Q"),
989 MockRead("J"),
990 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06991 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27992 };
[email protected]31a2bfe2010-02-09 08:03:39993 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
994 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01995 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27996 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
997 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22998 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
999 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:271000}
1001
1002// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:011003TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:271004 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351005 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:061006 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:271007 };
[email protected]31a2bfe2010-02-09 08:03:391008 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1009 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411010 EXPECT_THAT(out.rv, IsOk());
1011 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1012 EXPECT_EQ("HTT", out.response_data);
1013 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1014 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521015}
1016
[email protected]f9d44aa2008-09-23 23:57:171017// Simulate a 204 response, lacking a Content-Length header, sent over a
1018// persistent connection. The response should still terminate since a 204
1019// cannot have a response body.
bncd16676a2016-07-20 16:23:011020TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191021 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171022 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351023 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191024 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061025 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171026 };
[email protected]31a2bfe2010-02-09 08:03:391027 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1028 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011029 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171030 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1031 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221032 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1033 int64_t response_size = reads_size - strlen(junk);
1034 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171035}
1036
[email protected]0877e3d2009-10-17 22:29:571037// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011038TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191039 std::string final_chunk = "0\r\n\r\n";
1040 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1041 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571042 MockRead data_reads[] = {
1043 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1044 MockRead("5\r\nHello\r\n"),
1045 MockRead("1\r\n"),
1046 MockRead(" \r\n"),
1047 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191048 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061049 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571050 };
[email protected]31a2bfe2010-02-09 08:03:391051 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1052 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011053 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571054 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1055 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221056 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1057 int64_t response_size = reads_size - extra_data.size();
1058 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571059}
1060
[email protected]9fe44f52010-09-23 18:36:001061// Next tests deal with http://crbug.com/56344.
1062
bncd16676a2016-07-20 16:23:011063TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001064 MultipleContentLengthHeadersNoTransferEncoding) {
1065 MockRead data_reads[] = {
1066 MockRead("HTTP/1.1 200 OK\r\n"),
1067 MockRead("Content-Length: 10\r\n"),
1068 MockRead("Content-Length: 5\r\n\r\n"),
1069 };
1070 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1071 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001073}
1074
bncd16676a2016-07-20 16:23:011075TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041076 DuplicateContentLengthHeadersNoTransferEncoding) {
1077 MockRead data_reads[] = {
1078 MockRead("HTTP/1.1 200 OK\r\n"),
1079 MockRead("Content-Length: 5\r\n"),
1080 MockRead("Content-Length: 5\r\n\r\n"),
1081 MockRead("Hello"),
1082 };
1083 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1084 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011085 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041086 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1087 EXPECT_EQ("Hello", out.response_data);
1088}
1089
bncd16676a2016-07-20 16:23:011090TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041091 ComplexContentLengthHeadersNoTransferEncoding) {
1092 // More than 2 dupes.
1093 {
1094 MockRead data_reads[] = {
1095 MockRead("HTTP/1.1 200 OK\r\n"),
1096 MockRead("Content-Length: 5\r\n"),
1097 MockRead("Content-Length: 5\r\n"),
1098 MockRead("Content-Length: 5\r\n\r\n"),
1099 MockRead("Hello"),
1100 };
1101 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1102 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011103 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041104 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1105 EXPECT_EQ("Hello", out.response_data);
1106 }
1107 // HTTP/1.0
1108 {
1109 MockRead data_reads[] = {
1110 MockRead("HTTP/1.0 200 OK\r\n"),
1111 MockRead("Content-Length: 5\r\n"),
1112 MockRead("Content-Length: 5\r\n"),
1113 MockRead("Content-Length: 5\r\n\r\n"),
1114 MockRead("Hello"),
1115 };
1116 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1117 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011118 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041119 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1120 EXPECT_EQ("Hello", out.response_data);
1121 }
1122 // 2 dupes and one mismatched.
1123 {
1124 MockRead data_reads[] = {
1125 MockRead("HTTP/1.1 200 OK\r\n"),
1126 MockRead("Content-Length: 10\r\n"),
1127 MockRead("Content-Length: 10\r\n"),
1128 MockRead("Content-Length: 5\r\n\r\n"),
1129 };
1130 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1131 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011132 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041133 }
1134}
1135
bncd16676a2016-07-20 16:23:011136TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001137 MultipleContentLengthHeadersTransferEncoding) {
1138 MockRead data_reads[] = {
1139 MockRead("HTTP/1.1 200 OK\r\n"),
1140 MockRead("Content-Length: 666\r\n"),
1141 MockRead("Content-Length: 1337\r\n"),
1142 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1143 MockRead("5\r\nHello\r\n"),
1144 MockRead("1\r\n"),
1145 MockRead(" \r\n"),
1146 MockRead("5\r\nworld\r\n"),
1147 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061148 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001149 };
1150 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1151 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011152 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001153 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1154 EXPECT_EQ("Hello world", out.response_data);
1155}
1156
[email protected]1628fe92011-10-04 23:04:551157// Next tests deal with http://crbug.com/98895.
1158
1159// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011160TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551161 MockRead data_reads[] = {
1162 MockRead("HTTP/1.1 200 OK\r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1164 MockRead("Content-Length: 5\r\n\r\n"),
1165 MockRead("Hello"),
1166 };
1167 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1168 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011169 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551170 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1171 EXPECT_EQ("Hello", out.response_data);
1172}
1173
[email protected]54a9c6e52012-03-21 20:10:591174// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011175TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551176 MockRead data_reads[] = {
1177 MockRead("HTTP/1.1 200 OK\r\n"),
1178 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1179 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1180 MockRead("Content-Length: 5\r\n\r\n"),
1181 MockRead("Hello"),
1182 };
1183 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1184 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011185 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591186 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1187 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551188}
1189
1190// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011191TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551192 MockRead data_reads[] = {
1193 MockRead("HTTP/1.1 200 OK\r\n"),
1194 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1195 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1196 MockRead("Content-Length: 5\r\n\r\n"),
1197 MockRead("Hello"),
1198 };
1199 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1200 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011201 EXPECT_THAT(out.rv,
1202 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551203}
1204
[email protected]54a9c6e52012-03-21 20:10:591205// Checks that two identical Location headers result in no error.
1206// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011207TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551208 MockRead data_reads[] = {
1209 MockRead("HTTP/1.1 302 Redirect\r\n"),
1210 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591211 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551212 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061213 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551214 };
1215
1216 HttpRequestInfo request;
1217 request.method = "GET";
1218 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101219 request.traffic_annotation =
1220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551221
danakj1fd259a02016-04-16 03:17:091222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551224
1225 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071226 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551227
[email protected]49639fa2011-12-20 23:22:411228 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551229
tfarina42834112016-09-22 13:38:201230 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011231 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551232
robpercival214763f2016-07-01 23:27:011233 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551234
bnc691fda62016-08-12 00:43:161235 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521236 ASSERT_TRUE(response);
1237 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551238 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1239 std::string url;
1240 EXPECT_TRUE(response->headers->IsRedirect(&url));
1241 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471242 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551243}
1244
[email protected]1628fe92011-10-04 23:04:551245// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011246TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551247 MockRead data_reads[] = {
1248 MockRead("HTTP/1.1 302 Redirect\r\n"),
1249 MockRead("Location: http://good.com/\r\n"),
1250 MockRead("Location: http://evil.com/\r\n"),
1251 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061252 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551253 };
1254 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1255 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011256 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551257}
1258
[email protected]ef0faf2e72009-03-05 23:27:231259// Do a request using the HEAD method. Verify that we don't try to read the
1260// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011261TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421262 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231263 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231264 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101265 request.traffic_annotation =
1266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231267
danakj1fd259a02016-04-16 03:17:091268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091270 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161271 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091272 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1273 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271274
[email protected]ef0faf2e72009-03-05 23:27:231275 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131276 MockWrite("HEAD / HTTP/1.1\r\n"
1277 "Host: www.example.org\r\n"
1278 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231279 };
1280 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231281 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1282 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231283
mmenked39192ee2015-12-09 00:57:231284 // No response body because the test stops reading here.
1285 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231286 };
1287
[email protected]31a2bfe2010-02-09 08:03:391288 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1289 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231291
[email protected]49639fa2011-12-20 23:22:411292 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231293
tfarina42834112016-09-22 13:38:201294 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231296
1297 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011298 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231299
bnc691fda62016-08-12 00:43:161300 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521301 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231302
1303 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521304 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231305 EXPECT_EQ(1234, response->headers->GetContentLength());
1306 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471307 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091308 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1309 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231310
1311 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101312 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231313 bool has_server_header = response->headers->EnumerateHeader(
1314 &iter, "Server", &server_header);
1315 EXPECT_TRUE(has_server_header);
1316 EXPECT_EQ("Blah", server_header);
1317
1318 // Reading should give EOF right away, since there is no message body
1319 // (despite non-zero content-length).
1320 std::string response_data;
bnc691fda62016-08-12 00:43:161321 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011322 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231323 EXPECT_EQ("", response_data);
1324}
1325
bncd16676a2016-07-20 16:23:011326TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521328
1329 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351330 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1331 MockRead("hello"),
1332 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1333 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061334 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521335 };
[email protected]31a2bfe2010-02-09 08:03:391336 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071337 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521338
[email protected]0b0bf032010-09-21 18:08:501339 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521340 "hello", "world"
1341 };
1342
1343 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421344 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521345 request.method = "GET";
bncce36dca22015-04-21 22:11:231346 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101347 request.traffic_annotation =
1348 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521349
bnc691fda62016-08-12 00:43:161350 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271351
[email protected]49639fa2011-12-20 23:22:411352 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521353
tfarina42834112016-09-22 13:38:201354 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521356
1357 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011358 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521359
bnc691fda62016-08-12 00:43:161360 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521361 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521362
wezca1070932016-05-26 20:30:521363 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251364 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471365 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521366
1367 std::string response_data;
bnc691fda62016-08-12 00:43:161368 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011369 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251370 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521371 }
1372}
1373
bncd16676a2016-07-20 16:23:011374TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091375 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221376 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191377 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221378 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271379
[email protected]1c773ea12009-04-28 19:58:421380 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521381 request.method = "POST";
1382 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271383 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101384 request.traffic_annotation =
1385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521386
shivanishab9a143952016-09-19 17:23:411387 // Check the upload progress returned before initialization is correct.
1388 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1389 EXPECT_EQ(0u, progress.size());
1390 EXPECT_EQ(0u, progress.position());
1391
danakj1fd259a02016-04-16 03:17:091392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271394
initial.commit586acc5fe2008-07-26 22:42:521395 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351396 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1397 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1398 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061399 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521400 };
[email protected]31a2bfe2010-02-09 08:03:391401 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071402 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521403
[email protected]49639fa2011-12-20 23:22:411404 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521405
tfarina42834112016-09-22 13:38:201406 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521408
1409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521411
bnc691fda62016-08-12 00:43:161412 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521413 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521414
wezca1070932016-05-26 20:30:521415 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251416 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521417
1418 std::string response_data;
bnc691fda62016-08-12 00:43:161419 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011420 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251421 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521422}
1423
[email protected]3a2d3662009-03-27 03:49:141424// This test is almost the same as Ignores100 above, but the response contains
1425// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571426// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011427TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421428 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141429 request.method = "GET";
1430 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101431 request.traffic_annotation =
1432 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141433
danakj1fd259a02016-04-16 03:17:091434 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271436
[email protected]3a2d3662009-03-27 03:49:141437 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571438 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1439 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141440 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061441 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141442 };
[email protected]31a2bfe2010-02-09 08:03:391443 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071444 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141445
[email protected]49639fa2011-12-20 23:22:411446 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141447
tfarina42834112016-09-22 13:38:201448 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141450
1451 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011452 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141453
bnc691fda62016-08-12 00:43:161454 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521455 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141456
wezca1070932016-05-26 20:30:521457 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141458 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1459
1460 std::string response_data;
bnc691fda62016-08-12 00:43:161461 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011462 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141463 EXPECT_EQ("hello world", response_data);
1464}
1465
bncd16676a2016-07-20 16:23:011466TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081467 HttpRequestInfo request;
1468 request.method = "POST";
1469 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101470 request.traffic_annotation =
1471 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081472
danakj1fd259a02016-04-16 03:17:091473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081475
1476 MockRead data_reads[] = {
1477 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1478 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381479 };
zmo9528c9f42015-08-04 22:12:081480 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1481 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381482
zmo9528c9f42015-08-04 22:12:081483 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381484
tfarina42834112016-09-22 13:38:201485 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381487
zmo9528c9f42015-08-04 22:12:081488 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011489 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381490
zmo9528c9f42015-08-04 22:12:081491 std::string response_data;
bnc691fda62016-08-12 00:43:161492 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011493 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081494 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381495}
1496
bncd16676a2016-07-20 16:23:011497TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381498 HttpRequestInfo request;
1499 request.method = "POST";
1500 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101501 request.traffic_annotation =
1502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381503
danakj1fd259a02016-04-16 03:17:091504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271506
[email protected]ee9410e72010-01-07 01:42:381507 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061508 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381509 };
[email protected]31a2bfe2010-02-09 08:03:391510 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071511 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381512
[email protected]49639fa2011-12-20 23:22:411513 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381514
tfarina42834112016-09-22 13:38:201515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381517
1518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011519 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381520}
1521
[email protected]23e482282013-06-14 16:08:021522void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511523 const MockWrite* write_failure,
1524 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421525 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521526 request.method = "GET";
1527 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101528 request.traffic_annotation =
1529 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521530
vishal.b62985ca92015-04-17 08:45:511531 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071532 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271534
[email protected]202965992011-12-07 23:04:511535 // Written data for successfully sending both requests.
1536 MockWrite data1_writes[] = {
1537 MockWrite("GET / HTTP/1.1\r\n"
1538 "Host: www.foo.com\r\n"
1539 "Connection: keep-alive\r\n\r\n"),
1540 MockWrite("GET / HTTP/1.1\r\n"
1541 "Host: www.foo.com\r\n"
1542 "Connection: keep-alive\r\n\r\n")
1543 };
1544
1545 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521546 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351547 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1548 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061549 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521550 };
[email protected]202965992011-12-07 23:04:511551
1552 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491553 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511554 data1_writes[1] = *write_failure;
1555 } else {
1556 ASSERT_TRUE(read_failure);
1557 data1_reads[2] = *read_failure;
1558 }
1559
1560 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1561 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071562 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521563
1564 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351565 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1566 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061567 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521568 };
[email protected]31a2bfe2010-02-09 08:03:391569 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071570 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521571
thestig9d3bb0c2015-01-24 00:49:511572 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521573 "hello", "world"
1574 };
1575
mikecironef22f9812016-10-04 03:40:191576 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521577 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411578 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521579
bnc691fda62016-08-12 00:43:161580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521581
tfarina42834112016-09-22 13:38:201582 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521584
1585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011586 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521587
[email protected]58e32bb2013-01-21 18:23:251588 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161589 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251590 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1591 if (i == 0) {
1592 first_socket_log_id = load_timing_info.socket_log_id;
1593 } else {
1594 // The second request should be using a new socket.
1595 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1596 }
1597
bnc691fda62016-08-12 00:43:161598 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521599 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521600
wezca1070932016-05-26 20:30:521601 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471602 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251603 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521604
1605 std::string response_data;
bnc691fda62016-08-12 00:43:161606 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011607 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251608 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521609 }
1610}
[email protected]3d2a59b2008-09-26 19:44:251611
[email protected]a34f61ee2014-03-18 20:59:491612void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1613 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101614 const MockRead* read_failure,
1615 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491616 HttpRequestInfo request;
1617 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101618 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101619 request.traffic_annotation =
1620 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491621
vishal.b62985ca92015-04-17 08:45:511622 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491623 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091624 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491625
[email protected]09356c652014-03-25 15:36:101626 SSLSocketDataProvider ssl1(ASYNC, OK);
1627 SSLSocketDataProvider ssl2(ASYNC, OK);
1628 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361629 ssl1.next_proto = kProtoHTTP2;
1630 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101631 }
1632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491634
[email protected]09356c652014-03-25 15:36:101635 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411636 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491637 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411638 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151639 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411640 SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191641 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491642
[email protected]09356c652014-03-25 15:36:101643 // HTTP/1.1 versions of the request and response.
1644 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1645 "Host: www.foo.com\r\n"
1646 "Connection: keep-alive\r\n\r\n";
1647 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1648 const char kHttpData[] = "hello";
1649
1650 std::vector<MockRead> data1_reads;
1651 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491652 if (write_failure) {
1653 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101654 data1_writes.push_back(*write_failure);
1655 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491656 } else {
1657 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101658 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411659 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101660 } else {
1661 data1_writes.push_back(MockWrite(kHttpRequest));
1662 }
1663 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491664 }
1665
[email protected]09356c652014-03-25 15:36:101666 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1667 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491668 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1669
[email protected]09356c652014-03-25 15:36:101670 std::vector<MockRead> data2_reads;
1671 std::vector<MockWrite> data2_writes;
1672
1673 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411674 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101675
bncdf80d44fd2016-07-15 20:27:411676 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1677 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101678 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1679 } else {
1680 data2_writes.push_back(
1681 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1682
1683 data2_reads.push_back(
1684 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1685 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1686 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1687 }
rch8e6c6c42015-05-01 14:05:131688 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1689 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491690 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1691
1692 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591693 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491694 // Wait for the preconnect to complete.
1695 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1696 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101697 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491698
1699 // Make the request.
1700 TestCompletionCallback callback;
1701
bnc691fda62016-08-12 00:43:161702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491703
tfarina42834112016-09-22 13:38:201704 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491706
1707 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011708 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491709
1710 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161711 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101712 TestLoadTimingNotReused(
1713 load_timing_info,
1714 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491715
bnc691fda62016-08-12 00:43:161716 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521717 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491718
wezca1070932016-05-26 20:30:521719 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021720 if (response->was_fetched_via_spdy) {
1721 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1722 } else {
1723 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1724 }
[email protected]a34f61ee2014-03-18 20:59:491725
1726 std::string response_data;
bnc691fda62016-08-12 00:43:161727 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011728 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101729 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491730}
1731
Biljith Jayan45a41722017-08-16 18:43:141732// Test that we do not retry indefinitely when a server sends an error like
1733// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1734// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1735TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1736 HttpRequestInfo request;
1737 request.method = "GET";
1738 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101739 request.traffic_annotation =
1740 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141741
1742 // Check whether we give up after the third try.
1743
1744 // Construct an HTTP2 request and a "Go away" response.
1745 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1746 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291747 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141748 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1749 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1750
1751 // Three go away responses.
1752 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1753 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1754 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1755
1756 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1757 AddSSLSocketData();
1758 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1759 AddSSLSocketData();
1760 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1761 AddSSLSocketData();
1762
1763 TestCompletionCallback callback;
1764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1765 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1766
1767 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1769
1770 rv = callback.WaitForResult();
1771 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1772}
1773
1774TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1775 HttpRequestInfo request;
1776 request.method = "GET";
1777 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101778 request.traffic_annotation =
1779 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141780
1781 // Check whether we try atleast thrice before giving up.
1782
1783 // Construct an HTTP2 request and a "Go away" response.
1784 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1785 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Bence Békydcb30092018-02-11 01:32:291786 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway(0));
Biljith Jayan45a41722017-08-16 18:43:141787 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1788 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1789
1790 // Construct a non error HTTP2 response.
1791 SpdySerializedFrame spdy_response_no_error(
1792 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1793 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1794 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1795 CreateMockRead(spdy_data, 2)};
1796
1797 // Two error responses.
1798 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1799 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1800 // Followed by a success response.
1801 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1802
1803 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1804 AddSSLSocketData();
1805 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1806 AddSSLSocketData();
1807 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1808 AddSSLSocketData();
1809
1810 TestCompletionCallback callback;
1811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1813
1814 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1816
1817 rv = callback.WaitForResult();
1818 EXPECT_THAT(rv, IsOk());
1819}
1820
bncd16676a2016-07-20 16:23:011821TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061822 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511823 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1824}
1825
bncd16676a2016-07-20 16:23:011826TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061827 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511828 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251829}
1830
bncd16676a2016-07-20 16:23:011831TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061832 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511833 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251834}
1835
[email protected]d58ceea82014-06-04 10:55:541836// Make sure that on a 408 response (Request Timeout), the request is retried,
1837// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011838TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541839 MockRead read_failure(SYNCHRONOUS,
1840 "HTTP/1.1 408 Request Timeout\r\n"
1841 "Connection: Keep-Alive\r\n"
1842 "Content-Length: 6\r\n\r\n"
1843 "Pickle");
1844 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1845}
1846
bncd16676a2016-07-20 16:23:011847TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491848 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101849 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491850}
1851
bncd16676a2016-07-20 16:23:011852TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491853 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101854 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491855}
1856
bncd16676a2016-07-20 16:23:011857TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491858 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101859 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1860}
1861
bncd16676a2016-07-20 16:23:011862TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101863 MockRead read_failure(ASYNC, OK); // EOF
1864 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1865}
1866
[email protected]d58ceea82014-06-04 10:55:541867// Make sure that on a 408 response (Request Timeout), the request is retried,
1868// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011869TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541870 MockRead read_failure(SYNCHRONOUS,
1871 "HTTP/1.1 408 Request Timeout\r\n"
1872 "Connection: Keep-Alive\r\n"
1873 "Content-Length: 6\r\n\r\n"
1874 "Pickle");
1875 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1876 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1877}
1878
bncd16676a2016-07-20 16:23:011879TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101880 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1881 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1882}
1883
bncd16676a2016-07-20 16:23:011884TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101885 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1886 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1887}
1888
bncd16676a2016-07-20 16:23:011889TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101890 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1891 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1892}
1893
bncd16676a2016-07-20 16:23:011894TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101895 MockRead read_failure(ASYNC, OK); // EOF
1896 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491897}
1898
bncd16676a2016-07-20 16:23:011899TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421900 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251901 request.method = "GET";
bncce36dca22015-04-21 22:11:231902 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101903 request.traffic_annotation =
1904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251905
danakj1fd259a02016-04-16 03:17:091906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271908
[email protected]3d2a59b2008-09-26 19:44:251909 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061910 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351911 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1912 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061913 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251914 };
[email protected]31a2bfe2010-02-09 08:03:391915 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071916 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251917
[email protected]49639fa2011-12-20 23:22:411918 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251919
tfarina42834112016-09-22 13:38:201920 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251922
1923 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011924 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591925
1926 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161927 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591928 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251929}
1930
1931// What do various browsers do when the server closes a non-keepalive
1932// connection without sending any response header or body?
1933//
1934// IE7: error page
1935// Safari 3.1.2 (Windows): error page
1936// Firefox 3.0.1: blank page
1937// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421938// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1939// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011940TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251941 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061942 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351943 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1944 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061945 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251946 };
[email protected]31a2bfe2010-02-09 08:03:391947 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1948 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011949 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251950}
[email protected]1826a402014-01-08 15:40:481951
[email protected]7a5378b2012-11-04 03:25:171952// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1953// tests. There was a bug causing HttpNetworkTransaction to hang in the
1954// destructor in such situations.
1955// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011956TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171957 HttpRequestInfo request;
1958 request.method = "GET";
bncce36dca22015-04-21 22:11:231959 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101960 request.traffic_annotation =
1961 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171962
danakj1fd259a02016-04-16 03:17:091963 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581964 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191965 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171966
1967 MockRead data_reads[] = {
1968 MockRead("HTTP/1.0 200 OK\r\n"),
1969 MockRead("Connection: keep-alive\r\n"),
1970 MockRead("Content-Length: 100\r\n\r\n"),
1971 MockRead("hello"),
1972 MockRead(SYNCHRONOUS, 0),
1973 };
1974 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071975 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171976
1977 TestCompletionCallback callback;
1978
tfarina42834112016-09-22 13:38:201979 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171981
1982 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011983 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171984
1985 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501986 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171987 if (rv == ERR_IO_PENDING)
1988 rv = callback.WaitForResult();
1989 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501990 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011991 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171992
1993 trans.reset();
fdoray92e35a72016-06-10 15:54:551994 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171995 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1996}
1997
bncd16676a2016-07-20 16:23:011998TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171999 HttpRequestInfo request;
2000 request.method = "GET";
bncce36dca22015-04-21 22:11:232001 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102002 request.traffic_annotation =
2003 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172004
danakj1fd259a02016-04-16 03:17:092005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582006 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192007 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172008
2009 MockRead data_reads[] = {
2010 MockRead("HTTP/1.0 200 OK\r\n"),
2011 MockRead("Connection: keep-alive\r\n"),
2012 MockRead("Content-Length: 100\r\n\r\n"),
2013 MockRead(SYNCHRONOUS, 0),
2014 };
2015 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072016 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172017
2018 TestCompletionCallback callback;
2019
tfarina42834112016-09-22 13:38:202020 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172022
2023 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012024 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172025
2026 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:502027 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172028 if (rv == ERR_IO_PENDING)
2029 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012030 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172031
2032 trans.reset();
fdoray92e35a72016-06-10 15:54:552033 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172034 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2035}
2036
[email protected]0b0bf032010-09-21 18:08:502037// Test that we correctly reuse a keep-alive connection after not explicitly
2038// reading the body.
bncd16676a2016-07-20 16:23:012039TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132040 HttpRequestInfo request;
2041 request.method = "GET";
2042 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102043 request.traffic_annotation =
2044 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132045
vishal.b62985ca92015-04-17 08:45:512046 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072047 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092048 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272049
mmenkecc2298e2015-12-07 18:20:182050 const char* request_data =
2051 "GET / HTTP/1.1\r\n"
2052 "Host: www.foo.com\r\n"
2053 "Connection: keep-alive\r\n\r\n";
2054 MockWrite data_writes[] = {
2055 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2056 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2057 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2058 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2059 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2060 };
2061
[email protected]0b0bf032010-09-21 18:08:502062 // Note that because all these reads happen in the same
2063 // StaticSocketDataProvider, it shows that the same socket is being reused for
2064 // all transactions.
mmenkecc2298e2015-12-07 18:20:182065 MockRead data_reads[] = {
2066 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2067 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2068 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2069 MockRead(ASYNC, 7,
2070 "HTTP/1.1 302 Found\r\n"
2071 "Content-Length: 0\r\n\r\n"),
2072 MockRead(ASYNC, 9,
2073 "HTTP/1.1 302 Found\r\n"
2074 "Content-Length: 5\r\n\r\n"
2075 "hello"),
2076 MockRead(ASYNC, 11,
2077 "HTTP/1.1 301 Moved Permanently\r\n"
2078 "Content-Length: 0\r\n\r\n"),
2079 MockRead(ASYNC, 13,
2080 "HTTP/1.1 301 Moved Permanently\r\n"
2081 "Content-Length: 5\r\n\r\n"
2082 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132083
mmenkecc2298e2015-12-07 18:20:182084 // In the next two rounds, IsConnectedAndIdle returns false, due to
2085 // the set_busy_before_sync_reads(true) call, while the
2086 // HttpNetworkTransaction is being shut down, but the socket is still
2087 // reuseable. See http://crbug.com/544255.
2088 MockRead(ASYNC, 15,
2089 "HTTP/1.1 200 Hunky-Dory\r\n"
2090 "Content-Length: 5\r\n\r\n"),
2091 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132092
mmenkecc2298e2015-12-07 18:20:182093 MockRead(ASYNC, 18,
2094 "HTTP/1.1 200 Hunky-Dory\r\n"
2095 "Content-Length: 5\r\n\r\n"
2096 "he"),
2097 MockRead(SYNCHRONOUS, 19, "llo"),
2098
2099 // The body of the final request is actually read.
2100 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2101 MockRead(ASYNC, 22, "hello"),
2102 };
2103 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2104 arraysize(data_writes));
2105 data.set_busy_before_sync_reads(true);
2106 session_deps_.socket_factory->AddSocketDataProvider(&data);
2107
2108 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502109 std::string response_lines[kNumUnreadBodies];
2110
mikecironef22f9812016-10-04 03:40:192111 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182112 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412113 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132114
Jeremy Roman0579ed62017-08-29 15:56:192115 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582116 session.get());
[email protected]fc31d6a42010-06-24 18:05:132117
tfarina42834112016-09-22 13:38:202118 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012119 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132120
[email protected]58e32bb2013-01-21 18:23:252121 LoadTimingInfo load_timing_info;
2122 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2123 if (i == 0) {
2124 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2125 first_socket_log_id = load_timing_info.socket_log_id;
2126 } else {
2127 TestLoadTimingReused(load_timing_info);
2128 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2129 }
2130
[email protected]fc31d6a42010-06-24 18:05:132131 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182132 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132133
mmenkecc2298e2015-12-07 18:20:182134 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502135 response_lines[i] = response->headers->GetStatusLine();
2136
mmenkecc2298e2015-12-07 18:20:182137 // Delete the transaction without reading the response bodies. Then spin
2138 // the message loop, so the response bodies are drained.
2139 trans.reset();
2140 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132141 }
[email protected]0b0bf032010-09-21 18:08:502142
2143 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182144 "HTTP/1.1 204 No Content",
2145 "HTTP/1.1 205 Reset Content",
2146 "HTTP/1.1 304 Not Modified",
2147 "HTTP/1.1 302 Found",
2148 "HTTP/1.1 302 Found",
2149 "HTTP/1.1 301 Moved Permanently",
2150 "HTTP/1.1 301 Moved Permanently",
2151 "HTTP/1.1 200 Hunky-Dory",
2152 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502153 };
2154
mostynb91e0da982015-01-20 19:17:272155 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2156 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502157
2158 for (int i = 0; i < kNumUnreadBodies; ++i)
2159 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2160
[email protected]49639fa2011-12-20 23:22:412161 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202163 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012164 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162165 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182166 ASSERT_TRUE(response);
2167 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502168 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2169 std::string response_data;
bnc691fda62016-08-12 00:43:162170 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012171 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502172 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132173}
2174
mmenke5f94fda2016-06-02 20:54:132175// Sockets that receive extra data after a response is complete should not be
2176// reused.
bncd16676a2016-07-20 16:23:012177TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2179 MockWrite data_writes1[] = {
2180 MockWrite("HEAD / HTTP/1.1\r\n"
2181 "Host: www.borked.com\r\n"
2182 "Connection: keep-alive\r\n\r\n"),
2183 };
2184
2185 MockRead data_reads1[] = {
2186 MockRead("HTTP/1.1 200 OK\r\n"
2187 "Connection: keep-alive\r\n"
2188 "Content-Length: 22\r\n\r\n"
2189 "This server is borked."),
2190 };
2191
2192 MockWrite data_writes2[] = {
2193 MockWrite("GET /foo HTTP/1.1\r\n"
2194 "Host: www.borked.com\r\n"
2195 "Connection: keep-alive\r\n\r\n"),
2196 };
2197
2198 MockRead data_reads2[] = {
2199 MockRead("HTTP/1.1 200 OK\r\n"
2200 "Content-Length: 3\r\n\r\n"
2201 "foo"),
2202 };
2203 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2204 data_writes1, arraysize(data_writes1));
2205 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2206 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2207 data_writes2, arraysize(data_writes2));
2208 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2209
2210 TestCompletionCallback callback;
2211 HttpRequestInfo request1;
2212 request1.method = "HEAD";
2213 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102214 request1.traffic_annotation =
2215 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132216
bnc87dcefc2017-05-25 12:47:582217 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192218 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202219 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012220 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132221
2222 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2223 ASSERT_TRUE(response1);
2224 ASSERT_TRUE(response1->headers);
2225 EXPECT_EQ(200, response1->headers->response_code());
2226 EXPECT_TRUE(response1->headers->IsKeepAlive());
2227
2228 std::string response_data1;
robpercival214763f2016-07-01 23:27:012229 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132230 EXPECT_EQ("", response_data1);
2231 // Deleting the transaction attempts to release the socket back into the
2232 // socket pool.
2233 trans1.reset();
2234
2235 HttpRequestInfo request2;
2236 request2.method = "GET";
2237 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102238 request2.traffic_annotation =
2239 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132240
bnc87dcefc2017-05-25 12:47:582241 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192242 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202243 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012244 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132245
2246 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2247 ASSERT_TRUE(response2);
2248 ASSERT_TRUE(response2->headers);
2249 EXPECT_EQ(200, response2->headers->response_code());
2250
2251 std::string response_data2;
robpercival214763f2016-07-01 23:27:012252 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132253 EXPECT_EQ("foo", response_data2);
2254}
2255
bncd16676a2016-07-20 16:23:012256TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2258 MockWrite data_writes1[] = {
2259 MockWrite("GET / HTTP/1.1\r\n"
2260 "Host: www.borked.com\r\n"
2261 "Connection: keep-alive\r\n\r\n"),
2262 };
2263
2264 MockRead data_reads1[] = {
2265 MockRead("HTTP/1.1 200 OK\r\n"
2266 "Connection: keep-alive\r\n"
2267 "Content-Length: 22\r\n\r\n"
2268 "This server is borked."
2269 "Bonus data!"),
2270 };
2271
2272 MockWrite data_writes2[] = {
2273 MockWrite("GET /foo HTTP/1.1\r\n"
2274 "Host: www.borked.com\r\n"
2275 "Connection: keep-alive\r\n\r\n"),
2276 };
2277
2278 MockRead data_reads2[] = {
2279 MockRead("HTTP/1.1 200 OK\r\n"
2280 "Content-Length: 3\r\n\r\n"
2281 "foo"),
2282 };
2283 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2284 data_writes1, arraysize(data_writes1));
2285 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2286 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2287 data_writes2, arraysize(data_writes2));
2288 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2289
2290 TestCompletionCallback callback;
2291 HttpRequestInfo request1;
2292 request1.method = "GET";
2293 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102294 request1.traffic_annotation =
2295 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132296
bnc87dcefc2017-05-25 12:47:582297 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192298 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202299 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012300 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132301
2302 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2303 ASSERT_TRUE(response1);
2304 ASSERT_TRUE(response1->headers);
2305 EXPECT_EQ(200, response1->headers->response_code());
2306 EXPECT_TRUE(response1->headers->IsKeepAlive());
2307
2308 std::string response_data1;
robpercival214763f2016-07-01 23:27:012309 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132310 EXPECT_EQ("This server is borked.", response_data1);
2311 // Deleting the transaction attempts to release the socket back into the
2312 // socket pool.
2313 trans1.reset();
2314
2315 HttpRequestInfo request2;
2316 request2.method = "GET";
2317 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102318 request2.traffic_annotation =
2319 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132320
bnc87dcefc2017-05-25 12:47:582321 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192322 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202323 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012324 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132325
2326 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2327 ASSERT_TRUE(response2);
2328 ASSERT_TRUE(response2->headers);
2329 EXPECT_EQ(200, response2->headers->response_code());
2330
2331 std::string response_data2;
robpercival214763f2016-07-01 23:27:012332 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132333 EXPECT_EQ("foo", response_data2);
2334}
2335
bncd16676a2016-07-20 16:23:012336TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132337 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2338 MockWrite data_writes1[] = {
2339 MockWrite("GET / HTTP/1.1\r\n"
2340 "Host: www.borked.com\r\n"
2341 "Connection: keep-alive\r\n\r\n"),
2342 };
2343
2344 MockRead data_reads1[] = {
2345 MockRead("HTTP/1.1 200 OK\r\n"
2346 "Connection: keep-alive\r\n"
2347 "Transfer-Encoding: chunked\r\n\r\n"),
2348 MockRead("16\r\nThis server is borked.\r\n"),
2349 MockRead("0\r\n\r\nBonus data!"),
2350 };
2351
2352 MockWrite data_writes2[] = {
2353 MockWrite("GET /foo HTTP/1.1\r\n"
2354 "Host: www.borked.com\r\n"
2355 "Connection: keep-alive\r\n\r\n"),
2356 };
2357
2358 MockRead data_reads2[] = {
2359 MockRead("HTTP/1.1 200 OK\r\n"
2360 "Content-Length: 3\r\n\r\n"
2361 "foo"),
2362 };
2363 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2364 data_writes1, arraysize(data_writes1));
2365 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2366 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2367 data_writes2, arraysize(data_writes2));
2368 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2369
2370 TestCompletionCallback callback;
2371 HttpRequestInfo request1;
2372 request1.method = "GET";
2373 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102374 request1.traffic_annotation =
2375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132376
bnc87dcefc2017-05-25 12:47:582377 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192378 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202379 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012380 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132381
2382 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2383 ASSERT_TRUE(response1);
2384 ASSERT_TRUE(response1->headers);
2385 EXPECT_EQ(200, response1->headers->response_code());
2386 EXPECT_TRUE(response1->headers->IsKeepAlive());
2387
2388 std::string response_data1;
robpercival214763f2016-07-01 23:27:012389 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132390 EXPECT_EQ("This server is borked.", response_data1);
2391 // Deleting the transaction attempts to release the socket back into the
2392 // socket pool.
2393 trans1.reset();
2394
2395 HttpRequestInfo request2;
2396 request2.method = "GET";
2397 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102398 request2.traffic_annotation =
2399 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132400
bnc87dcefc2017-05-25 12:47:582401 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192402 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202403 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012404 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132405
2406 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2407 ASSERT_TRUE(response2);
2408 ASSERT_TRUE(response2->headers);
2409 EXPECT_EQ(200, response2->headers->response_code());
2410
2411 std::string response_data2;
robpercival214763f2016-07-01 23:27:012412 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132413 EXPECT_EQ("foo", response_data2);
2414}
2415
2416// This is a little different from the others - it tests the case that the
2417// HttpStreamParser doesn't know if there's extra data on a socket or not when
2418// the HttpNetworkTransaction is torn down, because the response body hasn't
2419// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012420TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2422 MockWrite data_writes1[] = {
2423 MockWrite("GET / HTTP/1.1\r\n"
2424 "Host: www.borked.com\r\n"
2425 "Connection: keep-alive\r\n\r\n"),
2426 };
2427
2428 MockRead data_reads1[] = {
2429 MockRead("HTTP/1.1 200 OK\r\n"
2430 "Connection: keep-alive\r\n"
2431 "Transfer-Encoding: chunked\r\n\r\n"),
2432 MockRead("16\r\nThis server is borked.\r\n"),
2433 MockRead("0\r\n\r\nBonus data!"),
2434 };
2435 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2436 data_writes1, arraysize(data_writes1));
2437 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2438
2439 TestCompletionCallback callback;
2440 HttpRequestInfo request1;
2441 request1.method = "GET";
2442 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102443 request1.traffic_annotation =
2444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132445
bnc87dcefc2017-05-25 12:47:582446 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192447 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582448 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012449 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132450
bnc87dcefc2017-05-25 12:47:582451 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132452 ASSERT_TRUE(response1);
2453 ASSERT_TRUE(response1->headers);
2454 EXPECT_EQ(200, response1->headers->response_code());
2455 EXPECT_TRUE(response1->headers->IsKeepAlive());
2456
2457 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2458 // response body.
bnc87dcefc2017-05-25 12:47:582459 trans.reset();
mmenke5f94fda2016-06-02 20:54:132460
2461 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2462 // socket can't be reused, rather than returning it to the socket pool.
2463 base::RunLoop().RunUntilIdle();
2464
2465 // There should be no idle sockets in the pool.
2466 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2467}
2468
[email protected]038e9a32008-10-08 22:40:162469// Test the request-challenge-retry sequence for basic auth.
2470// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012471TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422472 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162473 request.method = "GET";
bncce36dca22015-04-21 22:11:232474 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102475 request.traffic_annotation =
2476 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162477
vishal.b62985ca92015-04-17 08:45:512478 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072479 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272482
[email protected]f9ee6b52008-11-08 06:46:232483 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232484 MockWrite(
2485 "GET / HTTP/1.1\r\n"
2486 "Host: www.example.org\r\n"
2487 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232488 };
2489
[email protected]038e9a32008-10-08 22:40:162490 MockRead data_reads1[] = {
2491 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2492 // Give a couple authenticate options (only the middle one is actually
2493 // supported).
[email protected]22927ad2009-09-21 19:56:192494 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162495 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2496 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2497 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2498 // Large content-length -- won't matter, as connection will be reset.
2499 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062500 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162501 };
2502
2503 // After calling trans->RestartWithAuth(), this is the request we should
2504 // be issuing -- the final header line contains the credentials.
2505 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232506 MockWrite(
2507 "GET / HTTP/1.1\r\n"
2508 "Host: www.example.org\r\n"
2509 "Connection: keep-alive\r\n"
2510 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162511 };
2512
2513 // Lastly, the server responds with the actual content.
2514 MockRead data_reads2[] = {
2515 MockRead("HTTP/1.0 200 OK\r\n"),
2516 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2517 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062518 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162519 };
2520
[email protected]31a2bfe2010-02-09 08:03:392521 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2522 data_writes1, arraysize(data_writes1));
2523 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2524 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072525 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2526 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162527
[email protected]49639fa2011-12-20 23:22:412528 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162529
tfarina42834112016-09-22 13:38:202530 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162532
2533 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012534 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162535
[email protected]58e32bb2013-01-21 18:23:252536 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162537 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252538 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2539
sclittlefb249892015-09-10 21:33:222540 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162541 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222542 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162543 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192544
bnc691fda62016-08-12 00:43:162545 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522546 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042547 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162548
[email protected]49639fa2011-12-20 23:22:412549 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162550
bnc691fda62016-08-12 00:43:162551 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162553
2554 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012555 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162556
[email protected]58e32bb2013-01-21 18:23:252557 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162558 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252559 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2560 // The load timing after restart should have a new socket ID, and times after
2561 // those of the first load timing.
2562 EXPECT_LE(load_timing_info1.receive_headers_end,
2563 load_timing_info2.connect_timing.connect_start);
2564 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2565
sclittlefb249892015-09-10 21:33:222566 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162567 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222568 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162569 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192570
bnc691fda62016-08-12 00:43:162571 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522572 ASSERT_TRUE(response);
2573 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162574 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162575}
2576
ttuttled9dbc652015-09-29 20:00:592577// Test the request-challenge-retry sequence for basic auth.
2578// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012579TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592580 HttpRequestInfo request;
2581 request.method = "GET";
2582 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102583 request.traffic_annotation =
2584 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592585
2586 TestNetLog log;
2587 MockHostResolver* resolver = new MockHostResolver();
2588 session_deps_.net_log = &log;
2589 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092590 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592592
2593 resolver->rules()->ClearRules();
2594 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2595
2596 MockWrite data_writes1[] = {
2597 MockWrite("GET / HTTP/1.1\r\n"
2598 "Host: www.example.org\r\n"
2599 "Connection: keep-alive\r\n\r\n"),
2600 };
2601
2602 MockRead data_reads1[] = {
2603 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2604 // Give a couple authenticate options (only the middle one is actually
2605 // supported).
2606 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2607 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2608 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2609 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2610 // Large content-length -- won't matter, as connection will be reset.
2611 MockRead("Content-Length: 10000\r\n\r\n"),
2612 MockRead(SYNCHRONOUS, ERR_FAILED),
2613 };
2614
2615 // After calling trans->RestartWithAuth(), this is the request we should
2616 // be issuing -- the final header line contains the credentials.
2617 MockWrite data_writes2[] = {
2618 MockWrite("GET / HTTP/1.1\r\n"
2619 "Host: www.example.org\r\n"
2620 "Connection: keep-alive\r\n"
2621 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2622 };
2623
2624 // Lastly, the server responds with the actual content.
2625 MockRead data_reads2[] = {
2626 MockRead("HTTP/1.0 200 OK\r\n"),
2627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2628 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2629 };
2630
2631 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2632 data_writes1, arraysize(data_writes1));
2633 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2634 data_writes2, arraysize(data_writes2));
2635 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2636 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2637
2638 TestCompletionCallback callback1;
2639
bnc691fda62016-08-12 00:43:162640 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202641 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592642
2643 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162644 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592645 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2646
2647 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162648 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592649 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162650 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592651
bnc691fda62016-08-12 00:43:162652 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592653 ASSERT_TRUE(response);
2654 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2655
2656 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162657 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592658 ASSERT_FALSE(endpoint.address().empty());
2659 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2660
2661 resolver->rules()->ClearRules();
2662 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2663
2664 TestCompletionCallback callback2;
2665
bnc691fda62016-08-12 00:43:162666 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592667 AuthCredentials(kFoo, kBar), callback2.callback())));
2668
2669 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162670 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592671 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2672 // The load timing after restart should have a new socket ID, and times after
2673 // those of the first load timing.
2674 EXPECT_LE(load_timing_info1.receive_headers_end,
2675 load_timing_info2.connect_timing.connect_start);
2676 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2677
2678 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162679 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592680 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162681 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592682
bnc691fda62016-08-12 00:43:162683 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592684 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522685 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592686 EXPECT_EQ(100, response->headers->GetContentLength());
2687
bnc691fda62016-08-12 00:43:162688 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592689 ASSERT_FALSE(endpoint.address().empty());
2690 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2691}
2692
David Benjamin83ddfb32018-03-30 01:07:522693// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2694// will eventually give up.
2695TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2696 HttpRequestInfo request;
2697 request.method = "GET";
2698 request.url = GURL("http://www.example.org/");
2699 request.traffic_annotation =
2700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2701
2702 TestNetLog log;
2703 session_deps_.net_log = &log;
2704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2706
2707 MockWrite data_writes[] = {
2708 MockWrite("GET / HTTP/1.1\r\n"
2709 "Host: www.example.org\r\n"
2710 "Connection: keep-alive\r\n\r\n"),
2711 };
2712
2713 MockRead data_reads[] = {
2714 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2715 // Give a couple authenticate options (only the middle one is actually
2716 // supported).
2717 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2718 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2719 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2720 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2721 // Large content-length -- won't matter, as connection will be reset.
2722 MockRead("Content-Length: 10000\r\n\r\n"),
2723 MockRead(SYNCHRONOUS, ERR_FAILED),
2724 };
2725
2726 // After calling trans->RestartWithAuth(), this is the request we should
2727 // be issuing -- the final header line contains the credentials.
2728 MockWrite data_writes_restart[] = {
2729 MockWrite("GET / HTTP/1.1\r\n"
2730 "Host: www.example.org\r\n"
2731 "Connection: keep-alive\r\n"
2732 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2733 };
2734
2735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2736 arraysize(data_writes));
2737 session_deps_.socket_factory->AddSocketDataProvider(&data);
2738
2739 TestCompletionCallback callback;
2740 int rv = callback.GetResult(
2741 trans.Start(&request, callback.callback(), NetLogWithSource()));
2742
2743 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2744 for (int i = 0; i < 32; i++) {
2745 // Check the previous response was a 401.
2746 EXPECT_THAT(rv, IsOk());
2747 const HttpResponseInfo* response = trans.GetResponseInfo();
2748 ASSERT_TRUE(response);
2749 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2750
2751 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
2752 data_reads, arraysize(data_reads), data_writes_restart,
2753 arraysize(data_writes_restart)));
2754 session_deps_.socket_factory->AddSocketDataProvider(
2755 data_restarts.back().get());
2756 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2757 callback.callback()));
2758 }
2759
2760 // After too many tries, the transaction should have given up.
2761 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2762}
2763
bncd16676a2016-07-20 16:23:012764TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462765 HttpRequestInfo request;
2766 request.method = "GET";
bncce36dca22015-04-21 22:11:232767 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292768 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102769 request.traffic_annotation =
2770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462771
danakj1fd259a02016-04-16 03:17:092772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272774
[email protected]861fcd52009-08-26 02:33:462775 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232776 MockWrite(
2777 "GET / HTTP/1.1\r\n"
2778 "Host: www.example.org\r\n"
2779 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462780 };
2781
2782 MockRead data_reads[] = {
2783 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2784 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2785 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2786 // Large content-length -- won't matter, as connection will be reset.
2787 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062788 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462789 };
2790
[email protected]31a2bfe2010-02-09 08:03:392791 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2792 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072793 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412794 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462795
tfarina42834112016-09-22 13:38:202796 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462798
2799 rv = callback.WaitForResult();
2800 EXPECT_EQ(0, rv);
2801
sclittlefb249892015-09-10 21:33:222802 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162803 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222804 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162805 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192806
bnc691fda62016-08-12 00:43:162807 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522808 ASSERT_TRUE(response);
2809 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462810}
2811
[email protected]2d2697f92009-02-18 21:00:322812// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2813// connection.
bncd16676a2016-07-20 16:23:012814TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182815 // On the second pass, the body read of the auth challenge is synchronous, so
2816 // IsConnectedAndIdle returns false. The socket should still be drained and
2817 // reused. See http://crbug.com/544255.
2818 for (int i = 0; i < 2; ++i) {
2819 HttpRequestInfo request;
2820 request.method = "GET";
2821 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102822 request.traffic_annotation =
2823 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322824
mmenkecc2298e2015-12-07 18:20:182825 TestNetLog log;
2826 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272828
mmenkecc2298e2015-12-07 18:20:182829 MockWrite data_writes[] = {
2830 MockWrite(ASYNC, 0,
2831 "GET / HTTP/1.1\r\n"
2832 "Host: www.example.org\r\n"
2833 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322834
bnc691fda62016-08-12 00:43:162835 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182836 // be issuing -- the final header line contains the credentials.
2837 MockWrite(ASYNC, 6,
2838 "GET / HTTP/1.1\r\n"
2839 "Host: www.example.org\r\n"
2840 "Connection: keep-alive\r\n"
2841 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2842 };
[email protected]2d2697f92009-02-18 21:00:322843
mmenkecc2298e2015-12-07 18:20:182844 MockRead data_reads[] = {
2845 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2846 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2847 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2848 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2849 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322850
mmenkecc2298e2015-12-07 18:20:182851 // Lastly, the server responds with the actual content.
2852 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2853 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2854 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2855 MockRead(ASYNC, 10, "Hello"),
2856 };
[email protected]2d2697f92009-02-18 21:00:322857
mmenkecc2298e2015-12-07 18:20:182858 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2859 arraysize(data_writes));
2860 data.set_busy_before_sync_reads(true);
2861 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462862
mmenkecc2298e2015-12-07 18:20:182863 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322864
bnc691fda62016-08-12 00:43:162865 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202866 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012867 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322868
mmenkecc2298e2015-12-07 18:20:182869 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162870 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182871 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322872
bnc691fda62016-08-12 00:43:162873 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182874 ASSERT_TRUE(response);
2875 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322876
mmenkecc2298e2015-12-07 18:20:182877 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252878
bnc691fda62016-08-12 00:43:162879 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2880 callback2.callback());
robpercival214763f2016-07-01 23:27:012881 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322882
mmenkecc2298e2015-12-07 18:20:182883 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162884 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182885 TestLoadTimingReused(load_timing_info2);
2886 // The load timing after restart should have the same socket ID, and times
2887 // those of the first load timing.
2888 EXPECT_LE(load_timing_info1.receive_headers_end,
2889 load_timing_info2.send_start);
2890 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322891
bnc691fda62016-08-12 00:43:162892 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182893 ASSERT_TRUE(response);
2894 EXPECT_FALSE(response->auth_challenge);
2895 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322896
mmenkecc2298e2015-12-07 18:20:182897 std::string response_data;
bnc691fda62016-08-12 00:43:162898 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322899
mmenkecc2298e2015-12-07 18:20:182900 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162901 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182902 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162903 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182904 }
[email protected]2d2697f92009-02-18 21:00:322905}
2906
2907// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2908// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012909TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422910 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322911 request.method = "GET";
bncce36dca22015-04-21 22:11:232912 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102913 request.traffic_annotation =
2914 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322915
danakj1fd259a02016-04-16 03:17:092916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272917
[email protected]2d2697f92009-02-18 21:00:322918 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162919 MockWrite("GET / HTTP/1.1\r\n"
2920 "Host: www.example.org\r\n"
2921 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322922
bnc691fda62016-08-12 00:43:162923 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232924 // be issuing -- the final header line contains the credentials.
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"
2928 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322929 };
2930
[email protected]2d2697f92009-02-18 21:00:322931 MockRead data_reads1[] = {
2932 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2933 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312934 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322935
2936 // Lastly, the server responds with the actual content.
2937 MockRead("HTTP/1.1 200 OK\r\n"),
2938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502939 MockRead("Content-Length: 5\r\n\r\n"),
2940 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322941 };
2942
[email protected]2d0a4f92011-05-05 16:38:462943 // An incorrect reconnect would cause this to be read.
2944 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062945 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462946 };
2947
[email protected]31a2bfe2010-02-09 08:03:392948 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2949 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462950 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2951 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2953 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322954
[email protected]49639fa2011-12-20 23:22:412955 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322956
bnc691fda62016-08-12 00:43:162957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202958 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322960
2961 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012962 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322963
bnc691fda62016-08-12 00:43:162964 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522965 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042966 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322967
[email protected]49639fa2011-12-20 23:22:412968 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322969
bnc691fda62016-08-12 00:43:162970 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322972
2973 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012974 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322975
bnc691fda62016-08-12 00:43:162976 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522977 ASSERT_TRUE(response);
2978 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502979 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322980}
2981
2982// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2983// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012984TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422985 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322986 request.method = "GET";
bncce36dca22015-04-21 22:11:232987 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102988 request.traffic_annotation =
2989 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322990
danakj1fd259a02016-04-16 03:17:092991 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272992
[email protected]2d2697f92009-02-18 21:00:322993 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162994 MockWrite("GET / HTTP/1.1\r\n"
2995 "Host: www.example.org\r\n"
2996 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322997
bnc691fda62016-08-12 00:43:162998 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232999 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163000 MockWrite("GET / HTTP/1.1\r\n"
3001 "Host: www.example.org\r\n"
3002 "Connection: keep-alive\r\n"
3003 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323004 };
3005
3006 // Respond with 5 kb of response body.
3007 std::string large_body_string("Unauthorized");
3008 large_body_string.append(5 * 1024, ' ');
3009 large_body_string.append("\r\n");
3010
3011 MockRead data_reads1[] = {
3012 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3013 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3014 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3015 // 5134 = 12 + 5 * 1024 + 2
3016 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063017 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323018
3019 // Lastly, the server responds with the actual content.
3020 MockRead("HTTP/1.1 200 OK\r\n"),
3021 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503022 MockRead("Content-Length: 5\r\n\r\n"),
3023 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323024 };
3025
[email protected]2d0a4f92011-05-05 16:38:463026 // An incorrect reconnect would cause this to be read.
3027 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063028 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463029 };
3030
[email protected]31a2bfe2010-02-09 08:03:393031 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3032 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:463033 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3034 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:073035 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3036 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323037
[email protected]49639fa2011-12-20 23:22:413038 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323039
bnc691fda62016-08-12 00:43:163040 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203041 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323043
3044 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013045 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323046
bnc691fda62016-08-12 00:43:163047 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523048 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043049 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323050
[email protected]49639fa2011-12-20 23:22:413051 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323052
bnc691fda62016-08-12 00:43:163053 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323055
3056 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013057 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323058
bnc691fda62016-08-12 00:43:163059 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523060 ASSERT_TRUE(response);
3061 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503062 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323063}
3064
3065// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313066// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013067TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313068 HttpRequestInfo request;
3069 request.method = "GET";
bncce36dca22015-04-21 22:11:233070 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103071 request.traffic_annotation =
3072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313073
danakj1fd259a02016-04-16 03:17:093074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273075
[email protected]11203f012009-11-12 23:02:313076 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233077 MockWrite(
3078 "GET / HTTP/1.1\r\n"
3079 "Host: www.example.org\r\n"
3080 "Connection: keep-alive\r\n\r\n"),
3081 // This simulates the seemingly successful write to a closed connection
3082 // if the bug is not fixed.
3083 MockWrite(
3084 "GET / HTTP/1.1\r\n"
3085 "Host: www.example.org\r\n"
3086 "Connection: keep-alive\r\n"
3087 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313088 };
3089
3090 MockRead data_reads1[] = {
3091 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3092 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3093 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3094 MockRead("Content-Length: 14\r\n\r\n"),
3095 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063096 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313097 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063098 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313099 };
3100
bnc691fda62016-08-12 00:43:163101 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313102 // be issuing -- the final header line contains the credentials.
3103 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233104 MockWrite(
3105 "GET / HTTP/1.1\r\n"
3106 "Host: www.example.org\r\n"
3107 "Connection: keep-alive\r\n"
3108 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313109 };
3110
3111 // Lastly, the server responds with the actual content.
3112 MockRead data_reads2[] = {
3113 MockRead("HTTP/1.1 200 OK\r\n"),
3114 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503115 MockRead("Content-Length: 5\r\n\r\n"),
3116 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313117 };
3118
[email protected]31a2bfe2010-02-09 08:03:393119 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3120 data_writes1, arraysize(data_writes1));
3121 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3122 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313125
[email protected]49639fa2011-12-20 23:22:413126 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313127
bnc691fda62016-08-12 00:43:163128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203129 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313131
3132 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013133 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313134
bnc691fda62016-08-12 00:43:163135 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523136 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043137 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313138
[email protected]49639fa2011-12-20 23:22:413139 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313140
bnc691fda62016-08-12 00:43:163141 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313143
3144 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013145 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313146
bnc691fda62016-08-12 00:43:163147 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523148 ASSERT_TRUE(response);
3149 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503150 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313151}
3152
[email protected]394816e92010-08-03 07:38:593153// Test the request-challenge-retry sequence for basic auth, over a connection
3154// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013155TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013156 HttpRequestInfo request;
3157 request.method = "GET";
bncce36dca22015-04-21 22:11:233158 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013159 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293160 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103161 request.traffic_annotation =
3162 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013163
3164 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593165 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493166 ProxyResolutionService::CreateFixedFromPacResult(
3167 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513168 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013169 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093170 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013171
3172 // Since we have proxy, should try to establish tunnel.
3173 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543174 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173175 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543176 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013177 };
3178
mmenkee71e15332015-10-07 16:39:543179 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013180 // connection.
3181 MockRead data_reads1[] = {
3182 // No credentials.
3183 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3184 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543185 };
ttuttle34f63b52015-03-05 04:33:013186
mmenkee71e15332015-10-07 16:39:543187 // Since the first connection couldn't be reused, need to establish another
3188 // once given credentials.
3189 MockWrite data_writes2[] = {
3190 // After calling trans->RestartWithAuth(), this is the request we should
3191 // be issuing -- the final header line contains the credentials.
3192 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173193 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543194 "Proxy-Connection: keep-alive\r\n"
3195 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3196
3197 MockWrite("GET / HTTP/1.1\r\n"
3198 "Host: www.example.org\r\n"
3199 "Connection: keep-alive\r\n\r\n"),
3200 };
3201
3202 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013203 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3204
3205 MockRead("HTTP/1.1 200 OK\r\n"),
3206 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3207 MockRead("Content-Length: 5\r\n\r\n"),
3208 MockRead(SYNCHRONOUS, "hello"),
3209 };
3210
3211 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3212 data_writes1, arraysize(data_writes1));
3213 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543214 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3215 data_writes2, arraysize(data_writes2));
3216 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013217 SSLSocketDataProvider ssl(ASYNC, OK);
3218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3219
3220 TestCompletionCallback callback1;
3221
bnc87dcefc2017-05-25 12:47:583222 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193223 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013224
3225 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013227
3228 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013229 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463230 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013231 log.GetEntries(&entries);
3232 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003233 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3234 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013235 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003236 entries, pos,
3237 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3238 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013239
3240 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523241 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013242 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523243 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013244 EXPECT_EQ(407, response->headers->response_code());
3245 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3246 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3247
3248 LoadTimingInfo load_timing_info;
3249 // CONNECT requests and responses are handled at the connect job level, so
3250 // the transaction does not yet have a connection.
3251 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3252
3253 TestCompletionCallback callback2;
3254
3255 rv =
3256 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013258
3259 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013260 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013261
3262 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523263 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013264
3265 EXPECT_TRUE(response->headers->IsKeepAlive());
3266 EXPECT_EQ(200, response->headers->response_code());
3267 EXPECT_EQ(5, response->headers->GetContentLength());
3268 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3269
3270 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523271 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013272
3273 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3274 TestLoadTimingNotReusedWithPac(load_timing_info,
3275 CONNECT_TIMING_HAS_SSL_TIMES);
3276
3277 trans.reset();
3278 session->CloseAllConnections();
3279}
3280
3281// Test the request-challenge-retry sequence for basic auth, over a connection
3282// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013283TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593284 HttpRequestInfo request;
3285 request.method = "GET";
bncce36dca22015-04-21 22:11:233286 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593287 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293288 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103289 request.traffic_annotation =
3290 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593291
[email protected]cb9bf6ca2011-01-28 13:15:273292 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593293 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493294 ProxyResolutionService::CreateFixedFromPacResult(
3295 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513296 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073297 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273299
[email protected]394816e92010-08-03 07:38:593300 // Since we have proxy, should try to establish tunnel.
3301 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543302 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173303 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543304 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113305 };
3306
mmenkee71e15332015-10-07 16:39:543307 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083308 // connection.
3309 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543310 // No credentials.
3311 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3312 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3313 MockRead("Proxy-Connection: close\r\n\r\n"),
3314 };
mmenkee0b5c882015-08-26 20:29:113315
mmenkee71e15332015-10-07 16:39:543316 MockWrite data_writes2[] = {
3317 // After calling trans->RestartWithAuth(), this is the request we should
3318 // be issuing -- the final header line contains the credentials.
3319 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173320 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543321 "Proxy-Connection: keep-alive\r\n"
3322 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083323
mmenkee71e15332015-10-07 16:39:543324 MockWrite("GET / HTTP/1.1\r\n"
3325 "Host: www.example.org\r\n"
3326 "Connection: keep-alive\r\n\r\n"),
3327 };
3328
3329 MockRead data_reads2[] = {
3330 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3331
3332 MockRead("HTTP/1.1 200 OK\r\n"),
3333 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3334 MockRead("Content-Length: 5\r\n\r\n"),
3335 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593336 };
3337
3338 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3339 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073340 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543341 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3342 data_writes2, arraysize(data_writes2));
3343 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063344 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073345 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593346
[email protected]49639fa2011-12-20 23:22:413347 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593348
bnc87dcefc2017-05-25 12:47:583349 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193350 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503351
[email protected]49639fa2011-12-20 23:22:413352 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593354
3355 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013356 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463357 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403358 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593359 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003360 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3361 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593362 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403363 entries, pos,
mikecirone8b85c432016-09-08 19:11:003364 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3365 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593366
3367 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523368 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013369 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523370 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593371 EXPECT_EQ(407, response->headers->response_code());
3372 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043373 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593374
[email protected]029c83b62013-01-24 05:28:203375 LoadTimingInfo load_timing_info;
3376 // CONNECT requests and responses are handled at the connect job level, so
3377 // the transaction does not yet have a connection.
3378 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3379
[email protected]49639fa2011-12-20 23:22:413380 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593381
[email protected]49639fa2011-12-20 23:22:413382 rv = trans->RestartWithAuth(
3383 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013384 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593385
3386 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013387 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593388
3389 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523390 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593391
3392 EXPECT_TRUE(response->headers->IsKeepAlive());
3393 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503394 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593395 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3396
3397 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523398 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503399
[email protected]029c83b62013-01-24 05:28:203400 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3401 TestLoadTimingNotReusedWithPac(load_timing_info,
3402 CONNECT_TIMING_HAS_SSL_TIMES);
3403
[email protected]0b0bf032010-09-21 18:08:503404 trans.reset();
[email protected]102e27c2011-02-23 01:01:313405 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593406}
3407
[email protected]11203f012009-11-12 23:02:313408// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013409// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013410TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233411 // On the second pass, the body read of the auth challenge is synchronous, so
3412 // IsConnectedAndIdle returns false. The socket should still be drained and
3413 // reused. See http://crbug.com/544255.
3414 for (int i = 0; i < 2; ++i) {
3415 HttpRequestInfo request;
3416 request.method = "GET";
3417 request.url = GURL("https://www.example.org/");
3418 // Ensure that proxy authentication is attempted even
3419 // when the no authentication data flag is set.
3420 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103421 request.traffic_annotation =
3422 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013423
mmenked39192ee2015-12-09 00:57:233424 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593425 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493426 ProxyResolutionService::CreateFixed("myproxy:70",
3427 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233428 BoundTestNetLog log;
3429 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013431
bnc691fda62016-08-12 00:43:163432 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013433
mmenked39192ee2015-12-09 00:57:233434 // Since we have proxy, should try to establish tunnel.
3435 MockWrite data_writes1[] = {
3436 MockWrite(ASYNC, 0,
3437 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3438 "Host: www.example.org:443\r\n"
3439 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013440
bnc691fda62016-08-12 00:43:163441 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233442 // be issuing -- the final header line contains the credentials.
3443 MockWrite(ASYNC, 3,
3444 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3445 "Host: www.example.org:443\r\n"
3446 "Proxy-Connection: keep-alive\r\n"
3447 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3448 };
ttuttle34f63b52015-03-05 04:33:013449
mmenked39192ee2015-12-09 00:57:233450 // The proxy responds to the connect with a 407, using a persistent
3451 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3452 MockRead data_reads1[] = {
3453 // No credentials.
3454 MockRead(ASYNC, 1,
3455 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3456 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3457 "Proxy-Connection: keep-alive\r\n"
3458 "Content-Length: 10\r\n\r\n"),
3459 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013460
mmenked39192ee2015-12-09 00:57:233461 // Wrong credentials (wrong password).
3462 MockRead(ASYNC, 4,
3463 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3464 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3465 "Proxy-Connection: keep-alive\r\n"
3466 "Content-Length: 10\r\n\r\n"),
3467 // No response body because the test stops reading here.
3468 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3469 };
ttuttle34f63b52015-03-05 04:33:013470
mmenked39192ee2015-12-09 00:57:233471 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3472 arraysize(data_writes1));
3473 data1.set_busy_before_sync_reads(true);
3474 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013475
mmenked39192ee2015-12-09 00:57:233476 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013477
bnc691fda62016-08-12 00:43:163478 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013479 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013480
mmenked39192ee2015-12-09 00:57:233481 TestNetLogEntry::List entries;
3482 log.GetEntries(&entries);
3483 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003484 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3485 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233486 ExpectLogContainsSomewhere(
3487 entries, pos,
mikecirone8b85c432016-09-08 19:11:003488 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3489 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013490
bnc691fda62016-08-12 00:43:163491 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233492 ASSERT_TRUE(response);
3493 ASSERT_TRUE(response->headers);
3494 EXPECT_TRUE(response->headers->IsKeepAlive());
3495 EXPECT_EQ(407, response->headers->response_code());
3496 EXPECT_EQ(10, response->headers->GetContentLength());
3497 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3498 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013499
mmenked39192ee2015-12-09 00:57:233500 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013501
mmenked39192ee2015-12-09 00:57:233502 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163503 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3504 callback2.callback());
robpercival214763f2016-07-01 23:27:013505 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013506
bnc691fda62016-08-12 00:43:163507 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233508 ASSERT_TRUE(response);
3509 ASSERT_TRUE(response->headers);
3510 EXPECT_TRUE(response->headers->IsKeepAlive());
3511 EXPECT_EQ(407, response->headers->response_code());
3512 EXPECT_EQ(10, response->headers->GetContentLength());
3513 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3514 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013515
mmenked39192ee2015-12-09 00:57:233516 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3517 // out of scope.
3518 session->CloseAllConnections();
3519 }
ttuttle34f63b52015-03-05 04:33:013520}
3521
3522// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3523// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013524TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233525 // On the second pass, the body read of the auth challenge is synchronous, so
3526 // IsConnectedAndIdle returns false. The socket should still be drained and
3527 // reused. See http://crbug.com/544255.
3528 for (int i = 0; i < 2; ++i) {
3529 HttpRequestInfo request;
3530 request.method = "GET";
3531 request.url = GURL("https://www.example.org/");
3532 // Ensure that proxy authentication is attempted even
3533 // when the no authentication data flag is set.
3534 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103535 request.traffic_annotation =
3536 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233537
3538 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593539 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493540 ProxyResolutionService::CreateFixed("myproxy:70",
3541 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233542 BoundTestNetLog log;
3543 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233545
bnc691fda62016-08-12 00:43:163546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233547
3548 // Since we have proxy, should try to establish tunnel.
3549 MockWrite data_writes1[] = {
3550 MockWrite(ASYNC, 0,
3551 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3552 "Host: www.example.org:443\r\n"
3553 "Proxy-Connection: keep-alive\r\n\r\n"),
3554
bnc691fda62016-08-12 00:43:163555 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233556 // be issuing -- the final header line contains the credentials.
3557 MockWrite(ASYNC, 3,
3558 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3559 "Host: www.example.org:443\r\n"
3560 "Proxy-Connection: keep-alive\r\n"
3561 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3562 };
3563
3564 // The proxy responds to the connect with a 407, using a persistent
3565 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3566 MockRead data_reads1[] = {
3567 // No credentials.
3568 MockRead(ASYNC, 1,
3569 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3570 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3571 "Content-Length: 10\r\n\r\n"),
3572 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3573
3574 // Wrong credentials (wrong password).
3575 MockRead(ASYNC, 4,
3576 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3577 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3578 "Content-Length: 10\r\n\r\n"),
3579 // No response body because the test stops reading here.
3580 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3581 };
3582
3583 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3584 arraysize(data_writes1));
3585 data1.set_busy_before_sync_reads(true);
3586 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3587
3588 TestCompletionCallback callback1;
3589
bnc691fda62016-08-12 00:43:163590 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013591 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233592
3593 TestNetLogEntry::List entries;
3594 log.GetEntries(&entries);
3595 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003596 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3597 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233598 ExpectLogContainsSomewhere(
3599 entries, pos,
mikecirone8b85c432016-09-08 19:11:003600 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3601 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233602
bnc691fda62016-08-12 00:43:163603 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233604 ASSERT_TRUE(response);
3605 ASSERT_TRUE(response->headers);
3606 EXPECT_TRUE(response->headers->IsKeepAlive());
3607 EXPECT_EQ(407, response->headers->response_code());
3608 EXPECT_EQ(10, response->headers->GetContentLength());
3609 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3610 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3611
3612 TestCompletionCallback callback2;
3613
3614 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163615 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3616 callback2.callback());
robpercival214763f2016-07-01 23:27:013617 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233618
bnc691fda62016-08-12 00:43:163619 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233620 ASSERT_TRUE(response);
3621 ASSERT_TRUE(response->headers);
3622 EXPECT_TRUE(response->headers->IsKeepAlive());
3623 EXPECT_EQ(407, response->headers->response_code());
3624 EXPECT_EQ(10, response->headers->GetContentLength());
3625 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3626 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3627
3628 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3629 // out of scope.
3630 session->CloseAllConnections();
3631 }
3632}
3633
3634// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3635// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3636// the case the server sends extra data on the original socket, so it can't be
3637// reused.
bncd16676a2016-07-20 16:23:013638TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273639 HttpRequestInfo request;
3640 request.method = "GET";
bncce36dca22015-04-21 22:11:233641 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273642 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293643 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103644 request.traffic_annotation =
3645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273646
[email protected]2d2697f92009-02-18 21:00:323647 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593648 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493649 ProxyResolutionService::CreateFixedFromPacResult(
3650 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513651 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073652 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093653 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323654
[email protected]2d2697f92009-02-18 21:00:323655 // Since we have proxy, should try to establish tunnel.
3656 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233657 MockWrite(ASYNC, 0,
3658 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173659 "Host: www.example.org:443\r\n"
3660 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233661 };
[email protected]2d2697f92009-02-18 21:00:323662
mmenked39192ee2015-12-09 00:57:233663 // The proxy responds to the connect with a 407, using a persistent, but sends
3664 // extra data, so the socket cannot be reused.
3665 MockRead data_reads1[] = {
3666 // No credentials.
3667 MockRead(ASYNC, 1,
3668 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3669 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3670 "Content-Length: 10\r\n\r\n"),
3671 MockRead(SYNCHRONOUS, 2, "0123456789"),
3672 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3673 };
3674
3675 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233676 // After calling trans->RestartWithAuth(), this is the request we should
3677 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233678 MockWrite(ASYNC, 0,
3679 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173680 "Host: www.example.org:443\r\n"
3681 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233682 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3683
3684 MockWrite(ASYNC, 2,
3685 "GET / HTTP/1.1\r\n"
3686 "Host: www.example.org\r\n"
3687 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323688 };
3689
mmenked39192ee2015-12-09 00:57:233690 MockRead data_reads2[] = {
3691 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323692
mmenked39192ee2015-12-09 00:57:233693 MockRead(ASYNC, 3,
3694 "HTTP/1.1 200 OK\r\n"
3695 "Content-Type: text/html; charset=iso-8859-1\r\n"
3696 "Content-Length: 5\r\n\r\n"),
3697 // No response body because the test stops reading here.
3698 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323699 };
3700
mmenked39192ee2015-12-09 00:57:233701 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3702 arraysize(data_writes1));
3703 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073704 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233705 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3706 arraysize(data_writes2));
3707 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3708 SSLSocketDataProvider ssl(ASYNC, OK);
3709 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323710
[email protected]49639fa2011-12-20 23:22:413711 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323712
bnc87dcefc2017-05-25 12:47:583713 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193714 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323715
mmenked39192ee2015-12-09 00:57:233716 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013717 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233718
mmenke43758e62015-05-04 21:09:463719 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403720 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393721 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003722 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3723 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393724 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403725 entries, pos,
mikecirone8b85c432016-09-08 19:11:003726 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3727 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323728
[email protected]1c773ea12009-04-28 19:58:423729 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243730 ASSERT_TRUE(response);
3731 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323732 EXPECT_TRUE(response->headers->IsKeepAlive());
3733 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423734 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043735 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323736
mmenked39192ee2015-12-09 00:57:233737 LoadTimingInfo load_timing_info;
3738 // CONNECT requests and responses are handled at the connect job level, so
3739 // the transaction does not yet have a connection.
3740 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3741
[email protected]49639fa2011-12-20 23:22:413742 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323743
mmenked39192ee2015-12-09 00:57:233744 rv =
3745 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013746 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323747
[email protected]2d2697f92009-02-18 21:00:323748 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233749 EXPECT_EQ(200, response->headers->response_code());
3750 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423751 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133752
mmenked39192ee2015-12-09 00:57:233753 // The password prompt info should not be set.
3754 EXPECT_FALSE(response->auth_challenge);
3755
3756 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3757 TestLoadTimingNotReusedWithPac(load_timing_info,
3758 CONNECT_TIMING_HAS_SSL_TIMES);
3759
3760 trans.reset();
[email protected]102e27c2011-02-23 01:01:313761 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323762}
3763
mmenkee71e15332015-10-07 16:39:543764// Test the case a proxy closes a socket while the challenge body is being
3765// drained.
bncd16676a2016-07-20 16:23:013766TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543767 HttpRequestInfo request;
3768 request.method = "GET";
3769 request.url = GURL("https://www.example.org/");
3770 // Ensure that proxy authentication is attempted even
3771 // when the no authentication data flag is set.
3772 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103773 request.traffic_annotation =
3774 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543775
3776 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493777 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3778 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093779 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543780
bnc691fda62016-08-12 00:43:163781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543782
3783 // Since we have proxy, should try to establish tunnel.
3784 MockWrite data_writes1[] = {
3785 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173786 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543787 "Proxy-Connection: keep-alive\r\n\r\n"),
3788 };
3789
3790 // The proxy responds to the connect with a 407, using a persistent
3791 // connection.
3792 MockRead data_reads1[] = {
3793 // No credentials.
3794 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3795 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3796 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3797 // Server hands up in the middle of the body.
3798 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3799 };
3800
3801 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163802 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543803 // be issuing -- the final header line contains the credentials.
3804 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173805 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543806 "Proxy-Connection: keep-alive\r\n"
3807 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3808
3809 MockWrite("GET / HTTP/1.1\r\n"
3810 "Host: www.example.org\r\n"
3811 "Connection: keep-alive\r\n\r\n"),
3812 };
3813
3814 MockRead data_reads2[] = {
3815 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3816
3817 MockRead("HTTP/1.1 200 OK\r\n"),
3818 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3819 MockRead("Content-Length: 5\r\n\r\n"),
3820 MockRead(SYNCHRONOUS, "hello"),
3821 };
3822
3823 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3824 data_writes1, arraysize(data_writes1));
3825 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3826 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3827 data_writes2, arraysize(data_writes2));
3828 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3829 SSLSocketDataProvider ssl(ASYNC, OK);
3830 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3831
3832 TestCompletionCallback callback;
3833
tfarina42834112016-09-22 13:38:203834 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013835 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543836
bnc691fda62016-08-12 00:43:163837 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543838 ASSERT_TRUE(response);
3839 ASSERT_TRUE(response->headers);
3840 EXPECT_TRUE(response->headers->IsKeepAlive());
3841 EXPECT_EQ(407, response->headers->response_code());
3842 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3843
bnc691fda62016-08-12 00:43:163844 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013845 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543846
bnc691fda62016-08-12 00:43:163847 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543848 ASSERT_TRUE(response);
3849 ASSERT_TRUE(response->headers);
3850 EXPECT_TRUE(response->headers->IsKeepAlive());
3851 EXPECT_EQ(200, response->headers->response_code());
3852 std::string body;
bnc691fda62016-08-12 00:43:163853 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543854 EXPECT_EQ("hello", body);
3855}
3856
[email protected]a8e9b162009-03-12 00:06:443857// Test that we don't read the response body when we fail to establish a tunnel,
3858// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013859TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273860 HttpRequestInfo request;
3861 request.method = "GET";
bncce36dca22015-04-21 22:11:233862 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103863 request.traffic_annotation =
3864 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273865
[email protected]a8e9b162009-03-12 00:06:443866 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493867 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3868 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443869
danakj1fd259a02016-04-16 03:17:093870 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443871
bnc691fda62016-08-12 00:43:163872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443873
[email protected]a8e9b162009-03-12 00:06:443874 // Since we have proxy, should try to establish tunnel.
3875 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173876 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3877 "Host: www.example.org:443\r\n"
3878 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443879 };
3880
3881 // The proxy responds to the connect with a 407.
3882 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243883 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3884 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3885 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233886 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243887 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443888 };
3889
[email protected]31a2bfe2010-02-09 08:03:393890 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3891 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073892 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443893
[email protected]49639fa2011-12-20 23:22:413894 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443895
tfarina42834112016-09-22 13:38:203896 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443898
3899 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013900 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443901
bnc691fda62016-08-12 00:43:163902 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243903 ASSERT_TRUE(response);
3904 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443905 EXPECT_TRUE(response->headers->IsKeepAlive());
3906 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423907 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443908
3909 std::string response_data;
bnc691fda62016-08-12 00:43:163910 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013911 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183912
3913 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313914 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443915}
3916
ttuttle7933c112015-01-06 00:55:243917// Test that we don't pass extraneous headers from the proxy's response to the
3918// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013919TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243920 HttpRequestInfo request;
3921 request.method = "GET";
bncce36dca22015-04-21 22:11:233922 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103923 request.traffic_annotation =
3924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243925
3926 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493927 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3928 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243929
danakj1fd259a02016-04-16 03:17:093930 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243931
bnc691fda62016-08-12 00:43:163932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243933
3934 // Since we have proxy, should try to establish tunnel.
3935 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173936 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3937 "Host: www.example.org:443\r\n"
3938 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243939 };
3940
3941 // The proxy responds to the connect with a 407.
3942 MockRead data_reads[] = {
3943 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3944 MockRead("X-Foo: bar\r\n"),
3945 MockRead("Set-Cookie: foo=bar\r\n"),
3946 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3947 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233948 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243949 };
3950
3951 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3952 arraysize(data_writes));
3953 session_deps_.socket_factory->AddSocketDataProvider(&data);
3954
3955 TestCompletionCallback callback;
3956
tfarina42834112016-09-22 13:38:203957 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243959
3960 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013961 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243962
bnc691fda62016-08-12 00:43:163963 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243964 ASSERT_TRUE(response);
3965 ASSERT_TRUE(response->headers);
3966 EXPECT_TRUE(response->headers->IsKeepAlive());
3967 EXPECT_EQ(407, response->headers->response_code());
3968 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3969 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3970 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3971
3972 std::string response_data;
bnc691fda62016-08-12 00:43:163973 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013974 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243975
3976 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3977 session->CloseAllConnections();
3978}
3979
[email protected]8fdbcd22010-05-05 02:54:523980// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3981// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013982TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523983 HttpRequestInfo request;
3984 request.method = "GET";
bncce36dca22015-04-21 22:11:233985 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103986 request.traffic_annotation =
3987 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523988
[email protected]cb9bf6ca2011-01-28 13:15:273989 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093990 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163991 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273992
[email protected]8fdbcd22010-05-05 02:54:523993 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233994 MockWrite(
3995 "GET / HTTP/1.1\r\n"
3996 "Host: www.example.org\r\n"
3997 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523998 };
3999
4000 MockRead data_reads1[] = {
4001 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4002 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4003 // Large content-length -- won't matter, as connection will be reset.
4004 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064005 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524006 };
4007
4008 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4009 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074010 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524011
[email protected]49639fa2011-12-20 23:22:414012 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524013
tfarina42834112016-09-22 13:38:204014 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524016
4017 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014018 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524019}
4020
[email protected]7a67a8152010-11-05 18:31:104021// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4022// through a non-authenticating proxy. The request should fail with
4023// ERR_UNEXPECTED_PROXY_AUTH.
4024// Note that it is impossible to detect if an HTTP server returns a 407 through
4025// a non-authenticating proxy - there is nothing to indicate whether the
4026// response came from the proxy or the server, so it is treated as if the proxy
4027// issued the challenge.
bncd16676a2016-07-20 16:23:014028TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274029 HttpRequestInfo request;
4030 request.method = "GET";
bncce36dca22015-04-21 22:11:234031 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104032 request.traffic_annotation =
4033 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274034
Ramin Halavatica8d5252018-03-12 05:33:494035 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4036 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514037 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074038 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104040
[email protected]7a67a8152010-11-05 18:31:104041 // Since we have proxy, should try to establish tunnel.
4042 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174043 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4044 "Host: www.example.org:443\r\n"
4045 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104046
rsleevidb16bb02015-11-12 23:47:174047 MockWrite("GET / HTTP/1.1\r\n"
4048 "Host: www.example.org\r\n"
4049 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104050 };
4051
4052 MockRead data_reads1[] = {
4053 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4054
4055 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4056 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4057 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064058 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104059 };
4060
4061 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4062 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074063 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064064 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104066
[email protected]49639fa2011-12-20 23:22:414067 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104068
bnc691fda62016-08-12 00:43:164069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104070
bnc691fda62016-08-12 00:43:164071 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104073
4074 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014075 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464076 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404077 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104078 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004079 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4080 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104081 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404082 entries, pos,
mikecirone8b85c432016-09-08 19:11:004083 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4084 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104085}
[email protected]2df19bb2010-08-25 20:13:464086
mmenke2a1781d2015-10-07 19:25:334087// Test a proxy auth scheme that allows default credentials and a proxy server
4088// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014089TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334090 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4091 HttpRequestInfo request;
4092 request.method = "GET";
4093 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104094 request.traffic_annotation =
4095 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334096
4097 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594098 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494099 ProxyResolutionService::CreateFixedFromPacResult(
4100 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334101
Jeremy Roman0579ed62017-08-29 15:56:194102 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334103 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194104 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334105 mock_handler->set_allows_default_credentials(true);
4106 auth_handler_factory->AddMockHandler(mock_handler.release(),
4107 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484108 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334109
4110 // Add NetLog just so can verify load timing information gets a NetLog ID.
4111 NetLog net_log;
4112 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094113 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334114
4115 // Since we have proxy, should try to establish tunnel.
4116 MockWrite data_writes1[] = {
4117 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174118 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334119 "Proxy-Connection: keep-alive\r\n\r\n"),
4120 };
4121
4122 // The proxy responds to the connect with a 407, using a non-persistent
4123 // connection.
4124 MockRead data_reads1[] = {
4125 // No credentials.
4126 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4127 MockRead("Proxy-Authenticate: Mock\r\n"),
4128 MockRead("Proxy-Connection: close\r\n\r\n"),
4129 };
4130
4131 // Since the first connection couldn't be reused, need to establish another
4132 // once given credentials.
4133 MockWrite data_writes2[] = {
4134 // After calling trans->RestartWithAuth(), this is the request we should
4135 // be issuing -- the final header line contains the credentials.
4136 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174137 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334138 "Proxy-Connection: keep-alive\r\n"
4139 "Proxy-Authorization: auth_token\r\n\r\n"),
4140
4141 MockWrite("GET / HTTP/1.1\r\n"
4142 "Host: www.example.org\r\n"
4143 "Connection: keep-alive\r\n\r\n"),
4144 };
4145
4146 MockRead data_reads2[] = {
4147 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4148
4149 MockRead("HTTP/1.1 200 OK\r\n"),
4150 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4151 MockRead("Content-Length: 5\r\n\r\n"),
4152 MockRead(SYNCHRONOUS, "hello"),
4153 };
4154
4155 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4156 data_writes1, arraysize(data_writes1));
4157 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4158 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4159 data_writes2, arraysize(data_writes2));
4160 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4161 SSLSocketDataProvider ssl(ASYNC, OK);
4162 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4163
bnc87dcefc2017-05-25 12:47:584164 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194165 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334166
4167 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204168 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014169 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334170
4171 const HttpResponseInfo* response = trans->GetResponseInfo();
4172 ASSERT_TRUE(response);
4173 ASSERT_TRUE(response->headers);
4174 EXPECT_FALSE(response->headers->IsKeepAlive());
4175 EXPECT_EQ(407, response->headers->response_code());
4176 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4177 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524178 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334179
4180 LoadTimingInfo load_timing_info;
4181 // CONNECT requests and responses are handled at the connect job level, so
4182 // the transaction does not yet have a connection.
4183 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4184
4185 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014186 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334187 response = trans->GetResponseInfo();
4188 ASSERT_TRUE(response);
4189 ASSERT_TRUE(response->headers);
4190 EXPECT_TRUE(response->headers->IsKeepAlive());
4191 EXPECT_EQ(200, response->headers->response_code());
4192 EXPECT_EQ(5, response->headers->GetContentLength());
4193 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4194
4195 // The password prompt info should not be set.
4196 EXPECT_FALSE(response->auth_challenge);
4197
4198 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4199 TestLoadTimingNotReusedWithPac(load_timing_info,
4200 CONNECT_TIMING_HAS_SSL_TIMES);
4201
4202 trans.reset();
4203 session->CloseAllConnections();
4204}
4205
4206// Test a proxy auth scheme that allows default credentials and a proxy server
4207// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014208TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334209 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4210 HttpRequestInfo request;
4211 request.method = "GET";
4212 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104213 request.traffic_annotation =
4214 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334215
4216 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594217 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494218 ProxyResolutionService::CreateFixedFromPacResult(
4219 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334220
Jeremy Roman0579ed62017-08-29 15:56:194221 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334222 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194223 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334224 mock_handler->set_allows_default_credentials(true);
4225 auth_handler_factory->AddMockHandler(mock_handler.release(),
4226 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484227 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334228
4229 // Add NetLog just so can verify load timing information gets a NetLog ID.
4230 NetLog net_log;
4231 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094232 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334233
4234 // Should try to establish tunnel.
4235 MockWrite data_writes1[] = {
4236 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174237 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334238 "Proxy-Connection: keep-alive\r\n\r\n"),
4239
4240 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174241 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334242 "Proxy-Connection: keep-alive\r\n"
4243 "Proxy-Authorization: auth_token\r\n\r\n"),
4244 };
4245
4246 // The proxy responds to the connect with a 407, using a non-persistent
4247 // connection.
4248 MockRead data_reads1[] = {
4249 // No credentials.
4250 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4251 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4252 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4253 };
4254
4255 // Since the first connection was closed, need to establish another once given
4256 // credentials.
4257 MockWrite data_writes2[] = {
4258 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174259 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334260 "Proxy-Connection: keep-alive\r\n"
4261 "Proxy-Authorization: auth_token\r\n\r\n"),
4262
4263 MockWrite("GET / HTTP/1.1\r\n"
4264 "Host: www.example.org\r\n"
4265 "Connection: keep-alive\r\n\r\n"),
4266 };
4267
4268 MockRead data_reads2[] = {
4269 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4270
4271 MockRead("HTTP/1.1 200 OK\r\n"),
4272 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4273 MockRead("Content-Length: 5\r\n\r\n"),
4274 MockRead(SYNCHRONOUS, "hello"),
4275 };
4276
4277 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4278 data_writes1, arraysize(data_writes1));
4279 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4280 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4281 data_writes2, arraysize(data_writes2));
4282 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4283 SSLSocketDataProvider ssl(ASYNC, OK);
4284 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4285
bnc87dcefc2017-05-25 12:47:584286 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194287 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334288
4289 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204290 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014291 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334292
4293 const HttpResponseInfo* response = trans->GetResponseInfo();
4294 ASSERT_TRUE(response);
4295 ASSERT_TRUE(response->headers);
4296 EXPECT_TRUE(response->headers->IsKeepAlive());
4297 EXPECT_EQ(407, response->headers->response_code());
4298 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4299 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4300 EXPECT_FALSE(response->auth_challenge);
4301
4302 LoadTimingInfo load_timing_info;
4303 // CONNECT requests and responses are handled at the connect job level, so
4304 // the transaction does not yet have a connection.
4305 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4306
4307 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014308 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334309
4310 response = trans->GetResponseInfo();
4311 ASSERT_TRUE(response);
4312 ASSERT_TRUE(response->headers);
4313 EXPECT_TRUE(response->headers->IsKeepAlive());
4314 EXPECT_EQ(200, response->headers->response_code());
4315 EXPECT_EQ(5, response->headers->GetContentLength());
4316 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4317
4318 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524319 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334320
4321 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4322 TestLoadTimingNotReusedWithPac(load_timing_info,
4323 CONNECT_TIMING_HAS_SSL_TIMES);
4324
4325 trans.reset();
4326 session->CloseAllConnections();
4327}
4328
4329// Test a proxy auth scheme that allows default credentials and a proxy server
4330// that hangs up when credentials are initially sent, and hangs up again when
4331// they are retried.
bncd16676a2016-07-20 16:23:014332TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334333 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4334 HttpRequestInfo request;
4335 request.method = "GET";
4336 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104337 request.traffic_annotation =
4338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334339
4340 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594341 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494342 ProxyResolutionService::CreateFixedFromPacResult(
4343 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334344
Jeremy Roman0579ed62017-08-29 15:56:194345 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334346 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194347 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334348 mock_handler->set_allows_default_credentials(true);
4349 auth_handler_factory->AddMockHandler(mock_handler.release(),
4350 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484351 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334352
4353 // Add NetLog just so can verify load timing information gets a NetLog ID.
4354 NetLog net_log;
4355 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094356 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334357
4358 // Should try to establish tunnel.
4359 MockWrite data_writes1[] = {
4360 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174361 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334362 "Proxy-Connection: keep-alive\r\n\r\n"),
4363
4364 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174365 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334366 "Proxy-Connection: keep-alive\r\n"
4367 "Proxy-Authorization: auth_token\r\n\r\n"),
4368 };
4369
4370 // The proxy responds to the connect with a 407, and then hangs up after the
4371 // second request is sent.
4372 MockRead data_reads1[] = {
4373 // No credentials.
4374 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4375 MockRead("Content-Length: 0\r\n"),
4376 MockRead("Proxy-Connection: keep-alive\r\n"),
4377 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4378 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4379 };
4380
4381 // HttpNetworkTransaction sees a reused connection that was closed with
4382 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4383 // request.
4384 MockWrite data_writes2[] = {
4385 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174386 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334387 "Proxy-Connection: keep-alive\r\n\r\n"),
4388 };
4389
4390 // The proxy, having had more than enough of us, just hangs up.
4391 MockRead data_reads2[] = {
4392 // No credentials.
4393 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4394 };
4395
4396 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4397 data_writes1, arraysize(data_writes1));
4398 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4399 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4400 data_writes2, arraysize(data_writes2));
4401 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4402
bnc87dcefc2017-05-25 12:47:584403 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194404 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334405
4406 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204407 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014408 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334409
4410 const HttpResponseInfo* response = trans->GetResponseInfo();
4411 ASSERT_TRUE(response);
4412 ASSERT_TRUE(response->headers);
4413 EXPECT_TRUE(response->headers->IsKeepAlive());
4414 EXPECT_EQ(407, response->headers->response_code());
4415 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4416 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4417 EXPECT_FALSE(response->auth_challenge);
4418
4419 LoadTimingInfo load_timing_info;
4420 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4421
4422 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014423 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334424
4425 trans.reset();
4426 session->CloseAllConnections();
4427}
4428
4429// Test a proxy auth scheme that allows default credentials and a proxy server
4430// that hangs up when credentials are initially sent, and sends a challenge
4431// again they are retried.
bncd16676a2016-07-20 16:23:014432TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334433 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4434 HttpRequestInfo request;
4435 request.method = "GET";
4436 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104437 request.traffic_annotation =
4438 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334439
4440 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594441 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494442 ProxyResolutionService::CreateFixedFromPacResult(
4443 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334444
Jeremy Roman0579ed62017-08-29 15:56:194445 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334446 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194447 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334448 mock_handler->set_allows_default_credentials(true);
4449 auth_handler_factory->AddMockHandler(mock_handler.release(),
4450 HttpAuth::AUTH_PROXY);
4451 // Add another handler for the second challenge. It supports default
4452 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194453 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334454 mock_handler->set_allows_default_credentials(true);
4455 auth_handler_factory->AddMockHandler(mock_handler.release(),
4456 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484457 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334458
4459 // Add NetLog just so can verify load timing information gets a NetLog ID.
4460 NetLog net_log;
4461 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094462 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334463
4464 // Should try to establish tunnel.
4465 MockWrite data_writes1[] = {
4466 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174467 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334468 "Proxy-Connection: keep-alive\r\n\r\n"),
4469 };
4470
4471 // The proxy responds to the connect with a 407, using a non-persistent
4472 // connection.
4473 MockRead data_reads1[] = {
4474 // No credentials.
4475 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4476 MockRead("Proxy-Authenticate: Mock\r\n"),
4477 MockRead("Proxy-Connection: close\r\n\r\n"),
4478 };
4479
4480 // Since the first connection was closed, need to establish another once given
4481 // credentials.
4482 MockWrite data_writes2[] = {
4483 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174484 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334485 "Proxy-Connection: keep-alive\r\n"
4486 "Proxy-Authorization: auth_token\r\n\r\n"),
4487 };
4488
4489 MockRead data_reads2[] = {
4490 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4491 MockRead("Proxy-Authenticate: Mock\r\n"),
4492 MockRead("Proxy-Connection: close\r\n\r\n"),
4493 };
4494
4495 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4496 data_writes1, arraysize(data_writes1));
4497 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4498 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4499 data_writes2, arraysize(data_writes2));
4500 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4501 SSLSocketDataProvider ssl(ASYNC, OK);
4502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4503
bnc87dcefc2017-05-25 12:47:584504 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194505 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334506
4507 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204508 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014509 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334510
4511 const HttpResponseInfo* response = trans->GetResponseInfo();
4512 ASSERT_TRUE(response);
4513 ASSERT_TRUE(response->headers);
4514 EXPECT_EQ(407, response->headers->response_code());
4515 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4516 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4517 EXPECT_FALSE(response->auth_challenge);
4518
4519 LoadTimingInfo load_timing_info;
4520 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4521
4522 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014523 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334524 response = trans->GetResponseInfo();
4525 ASSERT_TRUE(response);
4526 ASSERT_TRUE(response->headers);
4527 EXPECT_EQ(407, response->headers->response_code());
4528 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4529 EXPECT_TRUE(response->auth_challenge);
4530
4531 trans.reset();
4532 session->CloseAllConnections();
4533}
4534
asankae2257db2016-10-11 22:03:164535// A more nuanced test than GenerateAuthToken test which asserts that
4536// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4537// unnecessarily invalidated, and that if the server co-operates, the
4538// authentication handshake can continue with the same scheme but with a
4539// different identity.
4540TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4541 HttpRequestInfo request;
4542 request.method = "GET";
4543 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104544 request.traffic_annotation =
4545 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164546
Jeremy Roman0579ed62017-08-29 15:56:194547 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164548 auth_handler_factory->set_do_init_from_challenge(true);
4549
4550 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194551 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164552 mock_handler->set_allows_default_credentials(true);
4553 mock_handler->set_allows_explicit_credentials(true);
4554 mock_handler->set_connection_based(true);
4555 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4556 auth_handler_factory->AddMockHandler(mock_handler.release(),
4557 HttpAuth::AUTH_SERVER);
4558
4559 // Add another handler for the second challenge. It supports default
4560 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194561 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164562 mock_handler->set_allows_default_credentials(true);
4563 mock_handler->set_allows_explicit_credentials(true);
4564 mock_handler->set_connection_based(true);
4565 auth_handler_factory->AddMockHandler(mock_handler.release(),
4566 HttpAuth::AUTH_SERVER);
4567 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4568
4569 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4570
4571 MockWrite data_writes1[] = {
4572 MockWrite("GET / HTTP/1.1\r\n"
4573 "Host: www.example.org\r\n"
4574 "Connection: keep-alive\r\n\r\n"),
4575 };
4576
4577 MockRead data_reads1[] = {
4578 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4579 "WWW-Authenticate: Mock\r\n"
4580 "Connection: keep-alive\r\n\r\n"),
4581 };
4582
4583 // Identical to data_writes1[]. The AuthHandler encounters a
4584 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4585 // transaction procceds without an authorization header.
4586 MockWrite data_writes2[] = {
4587 MockWrite("GET / HTTP/1.1\r\n"
4588 "Host: www.example.org\r\n"
4589 "Connection: keep-alive\r\n\r\n"),
4590 };
4591
4592 MockRead data_reads2[] = {
4593 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4594 "WWW-Authenticate: Mock\r\n"
4595 "Connection: keep-alive\r\n\r\n"),
4596 };
4597
4598 MockWrite data_writes3[] = {
4599 MockWrite("GET / HTTP/1.1\r\n"
4600 "Host: www.example.org\r\n"
4601 "Connection: keep-alive\r\n"
4602 "Authorization: auth_token\r\n\r\n"),
4603 };
4604
4605 MockRead data_reads3[] = {
4606 MockRead("HTTP/1.1 200 OK\r\n"
4607 "Content-Length: 5\r\n"
4608 "Content-Type: text/plain\r\n"
4609 "Connection: keep-alive\r\n\r\n"
4610 "Hello"),
4611 };
4612
4613 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4614 data_writes1, arraysize(data_writes1));
4615 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4616
4617 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4618 data_writes2, arraysize(data_writes2));
4619 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4620
4621 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4622 data_writes3, arraysize(data_writes3));
4623 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4624
bnc87dcefc2017-05-25 12:47:584625 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194626 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164627
4628 TestCompletionCallback callback;
4629 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4630 EXPECT_THAT(callback.GetResult(rv), IsOk());
4631
4632 const HttpResponseInfo* response = trans->GetResponseInfo();
4633 ASSERT_TRUE(response);
4634 ASSERT_TRUE(response->headers);
4635 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4636
4637 // The following three tests assert that an authentication challenge was
4638 // received and that the stack is ready to respond to the challenge using
4639 // ambient credentials.
4640 EXPECT_EQ(401, response->headers->response_code());
4641 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4642 EXPECT_FALSE(response->auth_challenge);
4643
4644 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4645 EXPECT_THAT(callback.GetResult(rv), IsOk());
4646 response = trans->GetResponseInfo();
4647 ASSERT_TRUE(response);
4648 ASSERT_TRUE(response->headers);
4649
4650 // The following three tests assert that an authentication challenge was
4651 // received and that the stack needs explicit credentials before it is ready
4652 // to respond to the challenge.
4653 EXPECT_EQ(401, response->headers->response_code());
4654 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4655 EXPECT_TRUE(response->auth_challenge);
4656
4657 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4658 EXPECT_THAT(callback.GetResult(rv), IsOk());
4659 response = trans->GetResponseInfo();
4660 ASSERT_TRUE(response);
4661 ASSERT_TRUE(response->headers);
4662 EXPECT_EQ(200, response->headers->response_code());
4663
4664 trans.reset();
4665 session->CloseAllConnections();
4666}
4667
Matt Menked1eb6d42018-01-17 04:54:064668// Proxy resolver that returns a proxy with the same host and port for different
4669// schemes, based on the path of the URL being requests.
4670class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4671 public:
4672 SameProxyWithDifferentSchemesProxyResolver() {}
4673 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4674
4675 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4676
4677 static HostPortPair ProxyHostPortPair() {
4678 return HostPortPair::FromString(ProxyHostPortPairAsString());
4679 }
4680
4681 // ProxyResolver implementation.
4682 int GetProxyForURL(const GURL& url,
4683 ProxyInfo* results,
4684 const CompletionCallback& callback,
4685 std::unique_ptr<Request>* request,
4686 const NetLogWithSource& /*net_log*/) override {
4687 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574688 results->set_traffic_annotation(
4689 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064690 if (url.path() == "/socks4") {
4691 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4692 return OK;
4693 }
4694 if (url.path() == "/socks5") {
4695 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4696 return OK;
4697 }
4698 if (url.path() == "/http") {
4699 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4700 return OK;
4701 }
4702 if (url.path() == "/https") {
4703 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4704 return OK;
4705 }
4706 NOTREACHED();
4707 return ERR_NOT_IMPLEMENTED;
4708 }
4709
4710 private:
4711 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4712};
4713
4714class SameProxyWithDifferentSchemesProxyResolverFactory
4715 : public ProxyResolverFactory {
4716 public:
4717 SameProxyWithDifferentSchemesProxyResolverFactory()
4718 : ProxyResolverFactory(false) {}
4719
Lily Houghton99597862018-03-07 16:40:424720 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4721 std::unique_ptr<ProxyResolver>* resolver,
4722 const CompletionCallback& callback,
4723 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064724 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4725 return OK;
4726 }
4727
4728 private:
4729 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4730};
4731
4732// Check that when different proxy schemes are all applied to a proxy at the
4733// same address, the sonnections are not grouped together. i.e., a request to
4734// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4735// request to foo.com using proxy.com as an HTTP proxy.
4736TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494737 session_deps_.proxy_resolution_service =
4738 std::make_unique<ProxyResolutionService>(
4739 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4740 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4741 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4742 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064743
4744 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4745
4746 MockWrite socks_writes[] = {
4747 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4748 kSOCKS4OkRequestLocalHostPort80Length),
4749 MockWrite(SYNCHRONOUS,
4750 "GET /socks4 HTTP/1.1\r\n"
4751 "Host: test\r\n"
4752 "Connection: keep-alive\r\n\r\n"),
4753 };
4754 MockRead socks_reads[] = {
4755 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4756 MockRead("HTTP/1.0 200 OK\r\n"
4757 "Connection: keep-alive\r\n"
4758 "Content-Length: 15\r\n\r\n"
4759 "SOCKS4 Response"),
4760 };
4761 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4762 socks_writes, arraysize(socks_writes));
4763 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4764
4765 const char kSOCKS5Request[] = {
4766 0x05, // Version
4767 0x01, // Command (CONNECT)
4768 0x00, // Reserved
4769 0x03, // Address type (DOMAINNAME)
4770 0x04, // Length of domain (4)
4771 't', 'e', 's', 't', // Domain string
4772 0x00, 0x50, // 16-bit port (80)
4773 };
4774 MockWrite socks5_writes[] = {
4775 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4776 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4777 MockWrite(SYNCHRONOUS,
4778 "GET /socks5 HTTP/1.1\r\n"
4779 "Host: test\r\n"
4780 "Connection: keep-alive\r\n\r\n"),
4781 };
4782 MockRead socks5_reads[] = {
4783 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4784 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4785 MockRead("HTTP/1.0 200 OK\r\n"
4786 "Connection: keep-alive\r\n"
4787 "Content-Length: 15\r\n\r\n"
4788 "SOCKS5 Response"),
4789 };
4790 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4791 socks5_writes, arraysize(socks5_writes));
4792 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4793
4794 MockWrite http_writes[] = {
4795 MockWrite(SYNCHRONOUS,
4796 "GET http://test/http HTTP/1.1\r\n"
4797 "Host: test\r\n"
4798 "Proxy-Connection: keep-alive\r\n\r\n"),
4799 };
4800 MockRead http_reads[] = {
4801 MockRead("HTTP/1.1 200 OK\r\n"
4802 "Proxy-Connection: keep-alive\r\n"
4803 "Content-Length: 13\r\n\r\n"
4804 "HTTP Response"),
4805 };
4806 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4807 http_writes, arraysize(http_writes));
4808 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4809
4810 MockWrite https_writes[] = {
4811 MockWrite(SYNCHRONOUS,
4812 "GET http://test/https HTTP/1.1\r\n"
4813 "Host: test\r\n"
4814 "Proxy-Connection: keep-alive\r\n\r\n"),
4815 };
4816 MockRead https_reads[] = {
4817 MockRead("HTTP/1.1 200 OK\r\n"
4818 "Proxy-Connection: keep-alive\r\n"
4819 "Content-Length: 14\r\n\r\n"
4820 "HTTPS Response"),
4821 };
4822 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4823 https_writes, arraysize(https_writes));
4824 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4825 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4826 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4827
4828 struct TestCase {
4829 GURL url;
4830 std::string expected_response;
4831 // How many idle sockets there should be in the SOCKS proxy socket pool
4832 // after the test.
4833 int expected_idle_socks_sockets;
4834 // How many idle sockets there should be in the HTTP proxy socket pool after
4835 // the test.
4836 int expected_idle_http_sockets;
4837 } const kTestCases[] = {
4838 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4839 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4840 {GURL("http://test/http"), "HTTP Response", 2, 1},
4841 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4842 };
4843
4844 for (const auto& test_case : kTestCases) {
4845 HttpRequestInfo request;
4846 request.method = "GET";
4847 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:104848 request.traffic_annotation =
4849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064850 std::unique_ptr<HttpNetworkTransaction> trans =
4851 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4852 session.get());
4853 TestCompletionCallback callback;
4854 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4855 EXPECT_THAT(callback.GetResult(rv), IsOk());
4856
4857 const HttpResponseInfo* response = trans->GetResponseInfo();
4858 ASSERT_TRUE(response);
4859 ASSERT_TRUE(response->headers);
4860 EXPECT_EQ(200, response->headers->response_code());
4861 std::string response_data;
4862 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4863 EXPECT_EQ(test_case.expected_response, response_data);
4864
4865 // Return the socket to the socket pool, so can make sure it's not used for
4866 // the next requests.
4867 trans.reset();
4868 base::RunLoop().RunUntilIdle();
4869
4870 // Check the number of idle sockets in the pool, to make sure that used
4871 // sockets are indeed being returned to the socket pool. If each request
4872 // doesn't return an idle socket to the pool, the test would incorrectly
4873 // pass.
4874 EXPECT_EQ(
4875 test_case.expected_idle_socks_sockets,
4876 session
4877 ->GetSocketPoolForSOCKSProxy(
4878 HttpNetworkSession::NORMAL_SOCKET_POOL,
4879 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4880 ->IdleSocketCount());
4881 EXPECT_EQ(
4882 test_case.expected_idle_http_sockets,
4883 session
4884 ->GetSocketPoolForHTTPProxy(
4885 HttpNetworkSession::NORMAL_SOCKET_POOL,
4886 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4887 ->IdleSocketCount());
4888 }
4889}
4890
[email protected]029c83b62013-01-24 05:28:204891// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014892TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204893 HttpRequestInfo request1;
4894 request1.method = "GET";
bncce36dca22015-04-21 22:11:234895 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104896 request1.traffic_annotation =
4897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204898
4899 HttpRequestInfo request2;
4900 request2.method = "GET";
bncce36dca22015-04-21 22:11:234901 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104902 request2.traffic_annotation =
4903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204904
4905 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494906 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4907 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514908 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074909 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204911
4912 // Since we have proxy, should try to establish tunnel.
4913 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174914 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4915 "Host: www.example.org:443\r\n"
4916 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204917
rsleevidb16bb02015-11-12 23:47:174918 MockWrite("GET /1 HTTP/1.1\r\n"
4919 "Host: www.example.org\r\n"
4920 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204921
rsleevidb16bb02015-11-12 23:47:174922 MockWrite("GET /2 HTTP/1.1\r\n"
4923 "Host: www.example.org\r\n"
4924 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204925 };
4926
4927 // The proxy responds to the connect with a 407, using a persistent
4928 // connection.
4929 MockRead data_reads1[] = {
4930 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4931
4932 MockRead("HTTP/1.1 200 OK\r\n"),
4933 MockRead("Content-Length: 1\r\n\r\n"),
4934 MockRead(SYNCHRONOUS, "1"),
4935
4936 MockRead("HTTP/1.1 200 OK\r\n"),
4937 MockRead("Content-Length: 2\r\n\r\n"),
4938 MockRead(SYNCHRONOUS, "22"),
4939 };
4940
4941 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4942 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074943 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204944 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074945 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204946
4947 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584948 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194949 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204950
4951 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014952 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204953
4954 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014955 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204956
4957 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524958 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474959 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524960 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204961 EXPECT_EQ(1, response1->headers->GetContentLength());
4962
4963 LoadTimingInfo load_timing_info1;
4964 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4965 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4966
4967 trans1.reset();
4968
4969 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584970 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194971 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204972
4973 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014974 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204975
4976 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014977 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204978
4979 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524980 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474981 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524982 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204983 EXPECT_EQ(2, response2->headers->GetContentLength());
4984
4985 LoadTimingInfo load_timing_info2;
4986 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4987 TestLoadTimingReused(load_timing_info2);
4988
4989 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4990
4991 trans2.reset();
4992 session->CloseAllConnections();
4993}
4994
4995// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014996TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204997 HttpRequestInfo request1;
4998 request1.method = "GET";
bncce36dca22015-04-21 22:11:234999 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105000 request1.traffic_annotation =
5001 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205002
5003 HttpRequestInfo request2;
5004 request2.method = "GET";
bncce36dca22015-04-21 22:11:235005 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105006 request2.traffic_annotation =
5007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205008
5009 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595010 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495011 ProxyResolutionService::CreateFixedFromPacResult(
5012 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515013 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075014 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095015 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205016
5017 // Since we have proxy, should try to establish tunnel.
5018 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175019 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5020 "Host: www.example.org:443\r\n"
5021 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205022
rsleevidb16bb02015-11-12 23:47:175023 MockWrite("GET /1 HTTP/1.1\r\n"
5024 "Host: www.example.org\r\n"
5025 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205026
rsleevidb16bb02015-11-12 23:47:175027 MockWrite("GET /2 HTTP/1.1\r\n"
5028 "Host: www.example.org\r\n"
5029 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205030 };
5031
5032 // The proxy responds to the connect with a 407, using a persistent
5033 // connection.
5034 MockRead data_reads1[] = {
5035 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5036
5037 MockRead("HTTP/1.1 200 OK\r\n"),
5038 MockRead("Content-Length: 1\r\n\r\n"),
5039 MockRead(SYNCHRONOUS, "1"),
5040
5041 MockRead("HTTP/1.1 200 OK\r\n"),
5042 MockRead("Content-Length: 2\r\n\r\n"),
5043 MockRead(SYNCHRONOUS, "22"),
5044 };
5045
5046 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5047 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075048 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205049 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205051
5052 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585053 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195054 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205055
5056 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015057 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205058
5059 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015060 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205061
5062 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525063 ASSERT_TRUE(response1);
5064 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205065 EXPECT_EQ(1, response1->headers->GetContentLength());
5066
5067 LoadTimingInfo load_timing_info1;
5068 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5069 TestLoadTimingNotReusedWithPac(load_timing_info1,
5070 CONNECT_TIMING_HAS_SSL_TIMES);
5071
5072 trans1.reset();
5073
5074 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585075 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195076 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205077
5078 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205080
5081 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015082 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205083
5084 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525085 ASSERT_TRUE(response2);
5086 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205087 EXPECT_EQ(2, response2->headers->GetContentLength());
5088
5089 LoadTimingInfo load_timing_info2;
5090 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5091 TestLoadTimingReusedWithPac(load_timing_info2);
5092
5093 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5094
5095 trans2.reset();
5096 session->CloseAllConnections();
5097}
5098
[email protected]2df19bb2010-08-25 20:13:465099// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015100TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275101 HttpRequestInfo request;
5102 request.method = "GET";
bncce36dca22015-04-21 22:11:235103 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105104 request.traffic_annotation =
5105 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275106
[email protected]2df19bb2010-08-25 20:13:465107 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495108 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5109 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515110 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075111 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465113
[email protected]2df19bb2010-08-25 20:13:465114 // Since we have proxy, should use full url
5115 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235116 MockWrite(
5117 "GET http://www.example.org/ HTTP/1.1\r\n"
5118 "Host: www.example.org\r\n"
5119 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465120 };
5121
5122 MockRead data_reads1[] = {
5123 MockRead("HTTP/1.1 200 OK\r\n"),
5124 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5125 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065126 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465127 };
5128
5129 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5130 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075131 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065132 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075133 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465134
[email protected]49639fa2011-12-20 23:22:415135 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465136
bnc691fda62016-08-12 00:43:165137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505138
bnc691fda62016-08-12 00:43:165139 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465141
5142 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015143 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465144
[email protected]58e32bb2013-01-21 18:23:255145 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165146 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255147 TestLoadTimingNotReused(load_timing_info,
5148 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5149
bnc691fda62016-08-12 00:43:165150 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525151 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465152
tbansal2ecbbc72016-10-06 17:15:475153 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465154 EXPECT_TRUE(response->headers->IsKeepAlive());
5155 EXPECT_EQ(200, response->headers->response_code());
5156 EXPECT_EQ(100, response->headers->GetContentLength());
5157 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5158
5159 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525160 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465161}
5162
[email protected]7642b5ae2010-09-01 20:55:175163// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015164TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275165 HttpRequestInfo request;
5166 request.method = "GET";
bncce36dca22015-04-21 22:11:235167 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105168 request.traffic_annotation =
5169 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275170
[email protected]7642b5ae2010-09-01 20:55:175171 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495172 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5173 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515174 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075175 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175177
bncce36dca22015-04-21 22:11:235178 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415179 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455180 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415181 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175182
bnc42331402016-07-25 13:36:155183 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415184 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175185 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415186 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175187 };
5188
rch8e6c6c42015-05-01 14:05:135189 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5190 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075191 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175192
[email protected]8ddf8322012-02-23 18:08:065193 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365194 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075195 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175196
[email protected]49639fa2011-12-20 23:22:415197 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175198
bnc691fda62016-08-12 00:43:165199 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505200
bnc691fda62016-08-12 00:43:165201 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175203
5204 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015205 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175206
[email protected]58e32bb2013-01-21 18:23:255207 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165208 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255209 TestLoadTimingNotReused(load_timing_info,
5210 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5211
bnc691fda62016-08-12 00:43:165212 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525213 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475214 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525215 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025216 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175217
5218 std::string response_data;
bnc691fda62016-08-12 00:43:165219 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235220 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175221}
5222
[email protected]1c173852014-06-19 12:51:505223// Verifies that a session which races and wins against the owning transaction
5224// (completing prior to host resolution), doesn't fail the transaction.
5225// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015226TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505227 HttpRequestInfo request;
5228 request.method = "GET";
bncce36dca22015-04-21 22:11:235229 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105230 request.traffic_annotation =
5231 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505232
5233 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495234 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5235 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515236 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505237 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505239
bncce36dca22015-04-21 22:11:235240 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415241 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455242 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415243 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505244
bnc42331402016-07-25 13:36:155245 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415246 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505247 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415248 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505249 };
5250
rch8e6c6c42015-05-01 14:05:135251 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5252 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505253 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5254
5255 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365256 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5258
5259 TestCompletionCallback callback1;
5260
bnc691fda62016-08-12 00:43:165261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505262
5263 // Stall the hostname resolution begun by the transaction.
5264 session_deps_.host_resolver->set_synchronous_mode(false);
5265 session_deps_.host_resolver->set_ondemand_mode(true);
5266
bnc691fda62016-08-12 00:43:165267 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505269
5270 // Race a session to the proxy, which completes first.
5271 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045272 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5273 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505274 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525275 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505276
5277 // Unstall the resolution begun by the transaction.
5278 session_deps_.host_resolver->set_ondemand_mode(true);
5279 session_deps_.host_resolver->ResolveAllPending();
5280
5281 EXPECT_FALSE(callback1.have_result());
5282 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015283 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505284
bnc691fda62016-08-12 00:43:165285 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525286 ASSERT_TRUE(response);
5287 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025288 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505289
5290 std::string response_data;
bnc691fda62016-08-12 00:43:165291 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505292 EXPECT_EQ(kUploadData, response_data);
5293}
5294
[email protected]dc7bd1c52010-11-12 00:01:135295// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015296TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275297 HttpRequestInfo request;
5298 request.method = "GET";
bncce36dca22015-04-21 22:11:235299 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105300 request.traffic_annotation =
5301 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275302
[email protected]79cb5c12011-09-12 13:12:045303 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495304 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5305 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515306 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075307 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135309
[email protected]dc7bd1c52010-11-12 00:01:135310 // The first request will be a bare GET, the second request will be a
5311 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455312 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415313 SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485314 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385315 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135316 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465317 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135318 };
bncdf80d44fd2016-07-15 20:27:415319 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5320 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485321 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135322 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415323 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135324 };
5325
5326 // The first response is a 407 proxy authentication challenge, and the second
5327 // response will be a 200 response since the second request includes a valid
5328 // Authorization header.
5329 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465330 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135331 };
bnc42331402016-07-25 13:36:155332 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235333 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415334 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5335 SpdySerializedFrame body_authentication(
5336 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155337 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415338 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135339 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415340 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465341 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415342 CreateMockRead(resp_data, 4),
5343 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135344 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135345 };
5346
rch8e6c6c42015-05-01 14:05:135347 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5348 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075349 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135350
[email protected]8ddf8322012-02-23 18:08:065351 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365352 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135354
[email protected]49639fa2011-12-20 23:22:415355 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135356
bnc691fda62016-08-12 00:43:165357 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135358
bnc691fda62016-08-12 00:43:165359 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135361
5362 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015363 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135364
bnc691fda62016-08-12 00:43:165365 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135366
wezca1070932016-05-26 20:30:525367 ASSERT_TRUE(response);
5368 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135369 EXPECT_EQ(407, response->headers->response_code());
5370 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435371 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135372
[email protected]49639fa2011-12-20 23:22:415373 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135374
bnc691fda62016-08-12 00:43:165375 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135377
5378 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015379 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135380
bnc691fda62016-08-12 00:43:165381 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135382
wezca1070932016-05-26 20:30:525383 ASSERT_TRUE(response_restart);
5384 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135385 EXPECT_EQ(200, response_restart->headers->response_code());
5386 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525387 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135388}
5389
[email protected]d9da5fe2010-10-13 22:37:165390// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015391TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275392 HttpRequestInfo request;
5393 request.method = "GET";
bncce36dca22015-04-21 22:11:235394 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105395 request.traffic_annotation =
5396 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275397
[email protected]d9da5fe2010-10-13 22:37:165398 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495399 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5400 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515401 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075402 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165404
bnc691fda62016-08-12 00:43:165405 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165406
bncce36dca22015-04-21 22:11:235407 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415408 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235409 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5410 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165411
bncce36dca22015-04-21 22:11:235412 const char get[] =
5413 "GET / HTTP/1.1\r\n"
5414 "Host: www.example.org\r\n"
5415 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415416 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195417 spdy_util_.ConstructSpdyDataFrame(1, get, false));
bnc42331402016-07-25 13:36:155418 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165419 const char resp[] = "HTTP/1.1 200 OK\r\n"
5420 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415421 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195422 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
bncdf80d44fd2016-07-15 20:27:415423 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195424 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
bncdf80d44fd2016-07-15 20:27:415425 SpdySerializedFrame window_update(
5426 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045427
5428 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415429 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5430 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045431 };
5432
[email protected]d9da5fe2010-10-13 22:37:165433 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415434 CreateMockRead(conn_resp, 1, ASYNC),
5435 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5436 CreateMockRead(wrapped_body, 4, ASYNC),
5437 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135438 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165439 };
5440
rch8e6c6c42015-05-01 14:05:135441 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5442 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075443 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165444
[email protected]8ddf8322012-02-23 18:08:065445 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365446 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065448 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165450
[email protected]49639fa2011-12-20 23:22:415451 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165452
bnc691fda62016-08-12 00:43:165453 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165455
5456 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015457 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165458
[email protected]58e32bb2013-01-21 18:23:255459 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165460 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255461 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5462
bnc691fda62016-08-12 00:43:165463 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525464 ASSERT_TRUE(response);
5465 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165466 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5467
5468 std::string response_data;
bnc691fda62016-08-12 00:43:165469 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165470 EXPECT_EQ("1234567890", response_data);
5471}
5472
5473// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015474TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5475 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385476
[email protected]cb9bf6ca2011-01-28 13:15:275477 HttpRequestInfo request;
5478 request.method = "GET";
bncce36dca22015-04-21 22:11:235479 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105480 request.traffic_annotation =
5481 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275482
[email protected]d9da5fe2010-10-13 22:37:165483 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495484 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5485 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515486 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075487 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095488 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165489
bnc691fda62016-08-12 00:43:165490 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165491
bncce36dca22015-04-21 22:11:235492 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415493 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235494 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5495 // fetch https://www.example.org/ via SPDY
5496 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415497 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495498 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415499 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155500 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415501 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155502 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415503 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025504 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415505 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5506 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025507 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415508 SpdySerializedFrame window_update_get_resp(
5509 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5510 SpdySerializedFrame window_update_body(
5511 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045512
5513 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415514 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5515 CreateMockWrite(window_update_get_resp, 6),
5516 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045517 };
5518
[email protected]d9da5fe2010-10-13 22:37:165519 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415520 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095521 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415522 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5523 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135524 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165525 };
5526
rch32320842015-05-16 15:57:095527 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5528 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075529 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165530
[email protected]8ddf8322012-02-23 18:08:065531 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365532 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075533 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065534 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365535 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075536 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165537
[email protected]49639fa2011-12-20 23:22:415538 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165539
bnc691fda62016-08-12 00:43:165540 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165542
rch32320842015-05-16 15:57:095543 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555544 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095545 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595546 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165547 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015548 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165549
[email protected]58e32bb2013-01-21 18:23:255550 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165551 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255552 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5553
bnc691fda62016-08-12 00:43:165554 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525555 ASSERT_TRUE(response);
5556 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025557 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165558
5559 std::string response_data;
bnc691fda62016-08-12 00:43:165560 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235561 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165562}
5563
5564// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015565TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275566 HttpRequestInfo request;
5567 request.method = "GET";
bncce36dca22015-04-21 22:11:235568 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105569 request.traffic_annotation =
5570 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275571
[email protected]d9da5fe2010-10-13 22:37:165572 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495573 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5574 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515575 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075576 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165578
bnc691fda62016-08-12 00:43:165579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165580
bncce36dca22015-04-21 22:11:235581 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415582 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235583 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415584 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085585 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165586
5587 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415588 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165589 };
5590
bnc42331402016-07-25 13:36:155591 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415592 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165593 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415594 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165595 };
5596
rch8e6c6c42015-05-01 14:05:135597 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5598 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075599 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165600
[email protected]8ddf8322012-02-23 18:08:065601 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365602 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065604 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365605 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165607
[email protected]49639fa2011-12-20 23:22:415608 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165609
bnc691fda62016-08-12 00:43:165610 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165612
5613 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015614 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165615
ttuttle960fcbf2016-04-19 13:26:325616 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165617}
5618
[email protected]f6c63db52013-02-02 00:35:225619// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5620// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015621TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225622 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5623 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495624 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5625 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515626 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075627 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095628 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505629 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225630
5631 HttpRequestInfo request1;
5632 request1.method = "GET";
bncce36dca22015-04-21 22:11:235633 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225634 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105635 request1.traffic_annotation =
5636 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225637
5638 HttpRequestInfo request2;
5639 request2.method = "GET";
bncce36dca22015-04-21 22:11:235640 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225641 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105642 request2.traffic_annotation =
5643 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225644
bncce36dca22015-04-21 22:11:235645 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415646 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235647 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155648 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225649
bncce36dca22015-04-21 22:11:235650 // Fetch https://www.example.org/ via HTTP.
5651 const char get1[] =
5652 "GET / HTTP/1.1\r\n"
5653 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225654 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415655 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195656 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225657 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5658 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415659 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195660 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415661 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195662 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415663 SpdySerializedFrame window_update(
5664 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225665
bncce36dca22015-04-21 22:11:235666 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295667 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275668 connect2_block[kHttp2MethodHeader] = "CONNECT";
5669 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155670 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5671 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395672
bnc42331402016-07-25 13:36:155673 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225674
bncce36dca22015-04-21 22:11:235675 // Fetch https://mail.example.org/ via HTTP.
5676 const char get2[] =
5677 "GET / HTTP/1.1\r\n"
5678 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225679 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415680 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195681 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225682 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5683 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415684 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195685 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
bncdf80d44fd2016-07-15 20:27:415686 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195687 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225688
5689 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415690 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5691 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225692 };
5693
5694 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415695 CreateMockRead(conn_resp1, 1, ASYNC),
5696 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5697 CreateMockRead(wrapped_body1, 4, ASYNC),
5698 CreateMockRead(conn_resp2, 6, ASYNC),
5699 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5700 CreateMockRead(wrapped_body2, 9, ASYNC),
5701 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225702 };
5703
mmenke11eb5152015-06-09 14:50:505704 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5705 arraysize(spdy_writes));
5706 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225707
5708 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365709 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225711 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225713 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225715
5716 TestCompletionCallback callback;
5717
bnc691fda62016-08-12 00:43:165718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205719 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015720 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225721
5722 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165723 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225724 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5725
bnc691fda62016-08-12 00:43:165726 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525727 ASSERT_TRUE(response);
5728 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225729 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5730
5731 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295732 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165733 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505734 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225735
bnc691fda62016-08-12 00:43:165736 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205737 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015738 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225739
5740 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165741 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225742 // Even though the SPDY connection is reused, a new tunnelled connection has
5743 // to be created, so the socket's load timing looks like a fresh connection.
5744 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5745
5746 // The requests should have different IDs, since they each are using their own
5747 // separate stream.
5748 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5749
bnc691fda62016-08-12 00:43:165750 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505751 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225752}
5753
5754// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5755// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015756TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225757 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5758 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495759 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5760 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515761 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075762 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095763 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505764 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225765
5766 HttpRequestInfo request1;
5767 request1.method = "GET";
bncce36dca22015-04-21 22:11:235768 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225769 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105770 request1.traffic_annotation =
5771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225772
5773 HttpRequestInfo request2;
5774 request2.method = "GET";
bncce36dca22015-04-21 22:11:235775 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225776 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105777 request2.traffic_annotation =
5778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225779
bncce36dca22015-04-21 22:11:235780 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415781 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235782 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155783 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225784
bncce36dca22015-04-21 22:11:235785 // Fetch https://www.example.org/ via HTTP.
5786 const char get1[] =
5787 "GET / HTTP/1.1\r\n"
5788 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225789 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415790 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195791 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225792 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5793 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415794 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195795 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415796 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195797 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415798 SpdySerializedFrame window_update(
5799 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225800
bncce36dca22015-04-21 22:11:235801 // Fetch https://www.example.org/2 via HTTP.
5802 const char get2[] =
5803 "GET /2 HTTP/1.1\r\n"
5804 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225805 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415806 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195807 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225808 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5809 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415810 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195811 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
bncdf80d44fd2016-07-15 20:27:415812 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195813 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225814
5815 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415816 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5817 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225818 };
5819
5820 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415821 CreateMockRead(conn_resp1, 1, ASYNC),
5822 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465823 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415824 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465825 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415826 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225827 };
5828
mmenke11eb5152015-06-09 14:50:505829 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5830 arraysize(spdy_writes));
5831 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225832
5833 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365834 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505835 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225836 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225838
5839 TestCompletionCallback callback;
5840
bnc87dcefc2017-05-25 12:47:585841 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195842 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205843 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225845
5846 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015847 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225848
5849 LoadTimingInfo load_timing_info;
5850 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5851 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5852
5853 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525854 ASSERT_TRUE(response);
5855 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225856 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5857
5858 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295859 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505860 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225861 trans.reset();
5862
bnc87dcefc2017-05-25 12:47:585863 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195864 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205865 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225867
[email protected]f6c63db52013-02-02 00:35:225868 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015869 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225870
5871 LoadTimingInfo load_timing_info2;
5872 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5873 TestLoadTimingReused(load_timing_info2);
5874
5875 // The requests should have the same ID.
5876 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5877
[email protected]90499482013-06-01 00:39:505878 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225879}
5880
5881// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5882// Proxy to different servers.
bncd16676a2016-07-20 16:23:015883TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225884 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495885 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5886 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515887 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075888 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095889 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505890 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225891
5892 HttpRequestInfo request1;
5893 request1.method = "GET";
bncce36dca22015-04-21 22:11:235894 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225895 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105896 request1.traffic_annotation =
5897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225898
5899 HttpRequestInfo request2;
5900 request2.method = "GET";
bncce36dca22015-04-21 22:11:235901 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225902 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105903 request2.traffic_annotation =
5904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225905
bncce36dca22015-04-21 22:11:235906 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265907 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235908 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415909 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155910 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5911 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Bence Békyd74f4382018-02-20 18:26:195912 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385913 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225914
bncce36dca22015-04-21 22:11:235915 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265916 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235917 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415918 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155919 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5920 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
Bence Békyd74f4382018-02-20 18:26:195921 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225922
5923 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415924 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225925 };
5926
5927 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415928 CreateMockRead(get_resp1, 1, ASYNC),
5929 CreateMockRead(body1, 2, ASYNC),
5930 CreateMockRead(get_resp2, 4, ASYNC),
5931 CreateMockRead(body2, 5, ASYNC),
5932 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225933 };
5934
mmenke11eb5152015-06-09 14:50:505935 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5936 arraysize(spdy_writes));
5937 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225938
5939 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365940 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225942
5943 TestCompletionCallback callback;
5944
bnc87dcefc2017-05-25 12:47:585945 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195946 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205947 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015948 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225949
5950 LoadTimingInfo load_timing_info;
5951 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5952 TestLoadTimingNotReused(load_timing_info,
5953 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5954
5955 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525956 ASSERT_TRUE(response);
5957 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025958 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225959
5960 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295961 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505962 rv = trans->Read(buf.get(), 256, callback.callback());
5963 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225964 // Delete the first request, so the second one can reuse the socket.
5965 trans.reset();
5966
bnc691fda62016-08-12 00:43:165967 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205968 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015969 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225970
5971 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165972 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225973 TestLoadTimingReused(load_timing_info2);
5974
5975 // The requests should have the same ID.
5976 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5977
bnc691fda62016-08-12 00:43:165978 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505979 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225980}
5981
[email protected]2df19bb2010-08-25 20:13:465982// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015983TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465984 HttpRequestInfo request;
5985 request.method = "GET";
bncce36dca22015-04-21 22:11:235986 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465987 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295988 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:105989 request.traffic_annotation =
5990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465991
[email protected]79cb5c12011-09-12 13:12:045992 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495993 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5994 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515995 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075996 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095997 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275998
[email protected]2df19bb2010-08-25 20:13:465999 // Since we have proxy, should use full url
6000 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166001 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6002 "Host: www.example.org\r\n"
6003 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466004
bnc691fda62016-08-12 00:43:166005 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236006 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166007 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6008 "Host: www.example.org\r\n"
6009 "Proxy-Connection: keep-alive\r\n"
6010 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466011 };
6012
6013 // The proxy responds to the GET with a 407, using a persistent
6014 // connection.
6015 MockRead data_reads1[] = {
6016 // No credentials.
6017 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6018 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6019 MockRead("Proxy-Connection: keep-alive\r\n"),
6020 MockRead("Content-Length: 0\r\n\r\n"),
6021
6022 MockRead("HTTP/1.1 200 OK\r\n"),
6023 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6024 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066025 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466026 };
6027
6028 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6029 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076030 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066031 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466033
[email protected]49639fa2011-12-20 23:22:416034 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466035
bnc691fda62016-08-12 00:43:166036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506037
bnc691fda62016-08-12 00:43:166038 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466040
6041 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016042 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466043
[email protected]58e32bb2013-01-21 18:23:256044 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166045 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256046 TestLoadTimingNotReused(load_timing_info,
6047 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6048
bnc691fda62016-08-12 00:43:166049 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526050 ASSERT_TRUE(response);
6051 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466052 EXPECT_EQ(407, response->headers->response_code());
6053 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436054 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466055
[email protected]49639fa2011-12-20 23:22:416056 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466057
bnc691fda62016-08-12 00:43:166058 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466060
6061 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016062 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466063
[email protected]58e32bb2013-01-21 18:23:256064 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166065 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256066 // Retrying with HTTP AUTH is considered to be reusing a socket.
6067 TestLoadTimingReused(load_timing_info);
6068
bnc691fda62016-08-12 00:43:166069 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526070 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466071
6072 EXPECT_TRUE(response->headers->IsKeepAlive());
6073 EXPECT_EQ(200, response->headers->response_code());
6074 EXPECT_EQ(100, response->headers->GetContentLength());
6075 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6076
6077 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526078 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466079}
6080
[email protected]23e482282013-06-14 16:08:026081void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086082 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426083 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086084 request.method = "GET";
bncce36dca22015-04-21 22:11:236085 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106086 request.traffic_annotation =
6087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086088
[email protected]cb9bf6ca2011-01-28 13:15:276089 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496090 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6091 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096092 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276093
[email protected]c744cf22009-02-27 07:28:086094 // Since we have proxy, should try to establish tunnel.
6095 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176096 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6097 "Host: www.example.org:443\r\n"
6098 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086099 };
6100
6101 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236102 status, MockRead("Content-Length: 10\r\n\r\n"),
6103 // No response body because the test stops reading here.
6104 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086105 };
6106
[email protected]31a2bfe2010-02-09 08:03:396107 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6108 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086110
[email protected]49639fa2011-12-20 23:22:416111 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086112
bnc691fda62016-08-12 00:43:166113 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506114
tfarina42834112016-09-22 13:38:206115 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086117
6118 rv = callback.WaitForResult();
6119 EXPECT_EQ(expected_status, rv);
6120}
6121
[email protected]23e482282013-06-14 16:08:026122void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236123 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086124 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426125 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086126}
6127
bncd16676a2016-07-20 16:23:016128TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086129 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6130}
6131
bncd16676a2016-07-20 16:23:016132TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086133 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6134}
6135
bncd16676a2016-07-20 16:23:016136TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086137 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6138}
6139
bncd16676a2016-07-20 16:23:016140TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086141 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6142}
6143
bncd16676a2016-07-20 16:23:016144TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086145 ConnectStatusHelper(
6146 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6147}
6148
bncd16676a2016-07-20 16:23:016149TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086150 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6151}
6152
bncd16676a2016-07-20 16:23:016153TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086154 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6155}
6156
bncd16676a2016-07-20 16:23:016157TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086158 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6159}
6160
bncd16676a2016-07-20 16:23:016161TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086162 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6163}
6164
bncd16676a2016-07-20 16:23:016165TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086166 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6167}
6168
bncd16676a2016-07-20 16:23:016169TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086170 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6171}
6172
bncd16676a2016-07-20 16:23:016173TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086174 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6175}
6176
bncd16676a2016-07-20 16:23:016177TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086178 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6179}
6180
bncd16676a2016-07-20 16:23:016181TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086182 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6183}
6184
bncd16676a2016-07-20 16:23:016185TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086186 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6187}
6188
bncd16676a2016-07-20 16:23:016189TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086190 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6191}
6192
bncd16676a2016-07-20 16:23:016193TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376194 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6195}
6196
bncd16676a2016-07-20 16:23:016197TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086198 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6199}
6200
bncd16676a2016-07-20 16:23:016201TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086202 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6203}
6204
bncd16676a2016-07-20 16:23:016205TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086206 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6207}
6208
bncd16676a2016-07-20 16:23:016209TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086210 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6211}
6212
bncd16676a2016-07-20 16:23:016213TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086214 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6215}
6216
bncd16676a2016-07-20 16:23:016217TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086218 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6219}
6220
bncd16676a2016-07-20 16:23:016221TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086222 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6223}
6224
bncd16676a2016-07-20 16:23:016225TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086226 ConnectStatusHelperWithExpectedStatus(
6227 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546228 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086229}
6230
bncd16676a2016-07-20 16:23:016231TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086232 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6233}
6234
bncd16676a2016-07-20 16:23:016235TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086236 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6237}
6238
bncd16676a2016-07-20 16:23:016239TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086240 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6241}
6242
bncd16676a2016-07-20 16:23:016243TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086244 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6245}
6246
bncd16676a2016-07-20 16:23:016247TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086248 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6249}
6250
bncd16676a2016-07-20 16:23:016251TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086252 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6253}
6254
bncd16676a2016-07-20 16:23:016255TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086256 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6257}
6258
bncd16676a2016-07-20 16:23:016259TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086260 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6261}
6262
bncd16676a2016-07-20 16:23:016263TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086264 ConnectStatusHelper(
6265 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6266}
6267
bncd16676a2016-07-20 16:23:016268TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086269 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6270}
6271
bncd16676a2016-07-20 16:23:016272TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086273 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6274}
6275
bncd16676a2016-07-20 16:23:016276TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086277 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6278}
6279
bncd16676a2016-07-20 16:23:016280TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086281 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6282}
6283
bncd16676a2016-07-20 16:23:016284TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086285 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6286}
6287
bncd16676a2016-07-20 16:23:016288TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086289 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6290}
6291
bncd16676a2016-07-20 16:23:016292TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086293 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6294}
6295
[email protected]038e9a32008-10-08 22:40:166296// Test the flow when both the proxy server AND origin server require
6297// authentication. Again, this uses basic auth for both since that is
6298// the simplest to mock.
bncd16676a2016-07-20 16:23:016299TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276300 HttpRequestInfo request;
6301 request.method = "GET";
bncce36dca22015-04-21 22:11:236302 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106303 request.traffic_annotation =
6304 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276305
[email protected]038e9a32008-10-08 22:40:166306 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496307 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6308 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096309 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076310
bnc691fda62016-08-12 00:43:166311 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166312
[email protected]f9ee6b52008-11-08 06:46:236313 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236314 MockWrite(
6315 "GET http://www.example.org/ HTTP/1.1\r\n"
6316 "Host: www.example.org\r\n"
6317 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236318 };
6319
[email protected]038e9a32008-10-08 22:40:166320 MockRead data_reads1[] = {
6321 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6322 // Give a couple authenticate options (only the middle one is actually
6323 // supported).
[email protected]22927ad2009-09-21 19:56:196324 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166325 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6326 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6327 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6328 // Large content-length -- won't matter, as connection will be reset.
6329 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066330 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166331 };
6332
bnc691fda62016-08-12 00:43:166333 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166334 // request we should be issuing -- the final header line contains the
6335 // proxy's credentials.
6336 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236337 MockWrite(
6338 "GET http://www.example.org/ HTTP/1.1\r\n"
6339 "Host: www.example.org\r\n"
6340 "Proxy-Connection: keep-alive\r\n"
6341 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166342 };
6343
6344 // Now the proxy server lets the request pass through to origin server.
6345 // The origin server responds with a 401.
6346 MockRead data_reads2[] = {
6347 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6348 // Note: We are using the same realm-name as the proxy server. This is
6349 // completely valid, as realms are unique across hosts.
6350 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6351 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6352 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066353 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166354 };
6355
bnc691fda62016-08-12 00:43:166356 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166357 // the credentials for both the proxy and origin server.
6358 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236359 MockWrite(
6360 "GET http://www.example.org/ HTTP/1.1\r\n"
6361 "Host: www.example.org\r\n"
6362 "Proxy-Connection: keep-alive\r\n"
6363 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6364 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166365 };
6366
6367 // Lastly we get the desired content.
6368 MockRead data_reads3[] = {
6369 MockRead("HTTP/1.0 200 OK\r\n"),
6370 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6371 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066372 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166373 };
6374
[email protected]31a2bfe2010-02-09 08:03:396375 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6376 data_writes1, arraysize(data_writes1));
6377 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6378 data_writes2, arraysize(data_writes2));
6379 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6380 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076381 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6382 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6383 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166384
[email protected]49639fa2011-12-20 23:22:416385 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166386
tfarina42834112016-09-22 13:38:206387 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016388 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166389
6390 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016391 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166392
bnc691fda62016-08-12 00:43:166393 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526394 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046395 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166396
[email protected]49639fa2011-12-20 23:22:416397 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166398
bnc691fda62016-08-12 00:43:166399 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166401
6402 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016403 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166404
bnc691fda62016-08-12 00:43:166405 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526406 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046407 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166408
[email protected]49639fa2011-12-20 23:22:416409 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166410
bnc691fda62016-08-12 00:43:166411 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6412 callback3.callback());
robpercival214763f2016-07-01 23:27:016413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166414
6415 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016416 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166417
bnc691fda62016-08-12 00:43:166418 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526419 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166420 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166421}
[email protected]4ddaf2502008-10-23 18:26:196422
[email protected]ea9dc9a2009-09-05 00:43:326423// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6424// can't hook into its internals to cause it to generate predictable NTLM
6425// authorization headers.
6426#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376427// The NTLM authentication unit tests are based on known test data from the
6428// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6429// flow rather than the implementation of the NTLM protocol. See net/ntlm
6430// for the implementation and testing of the protocol.
6431//
6432// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296433
6434// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556435TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426436 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246437 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556438 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106439 request.traffic_annotation =
6440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546441
6442 // Ensure load is not disrupted by flags which suppress behaviour specific
6443 // to other auth schemes.
6444 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246445
Zentaro Kavanagh6ccee512017-09-28 18:34:096446 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6447 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276449
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376450 // Generate the NTLM messages based on known test data.
6451 std::string negotiate_msg;
6452 std::string challenge_msg;
6453 std::string authenticate_msg;
6454 base::Base64Encode(
6455 base::StringPiece(
6456 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6457 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6458 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556459 base::Base64Encode(
6460 base::StringPiece(
6461 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6462 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6463 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376464 base::Base64Encode(
6465 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096466 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556467 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6468 arraysize(
6469 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376470 &authenticate_msg);
6471
[email protected]3f918782009-02-28 01:29:246472 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556473 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6474 "Host: server\r\n"
6475 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246476 };
6477
6478 MockRead data_reads1[] = {
6479 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046480 // Negotiate and NTLM are often requested together. However, we only want
6481 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6482 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246483 MockRead("WWW-Authenticate: NTLM\r\n"),
6484 MockRead("Connection: close\r\n"),
6485 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366486 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246487 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246488 };
6489
6490 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166491 // After restarting with a null identity, this is the
6492 // request we should be issuing -- the final header line contains a Type
6493 // 1 message.
6494 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556495 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166496 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376497 "Authorization: NTLM "),
6498 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246499
bnc691fda62016-08-12 00:43:166500 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376501 // (using correct credentials). The second request continues on the
6502 // same connection.
bnc691fda62016-08-12 00:43:166503 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556504 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166505 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376506 "Authorization: NTLM "),
6507 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246508 };
6509
6510 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026511 // The origin server responds with a Type 2 message.
6512 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376513 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6514 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026515 MockRead("Content-Type: text/html\r\n\r\n"),
6516 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246517
Bence Béky1e4ef192017-09-18 19:58:026518 // Lastly we get the desired content.
6519 MockRead("HTTP/1.1 200 OK\r\n"),
6520 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6521 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246522 };
6523
[email protected]31a2bfe2010-02-09 08:03:396524 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6525 data_writes1, arraysize(data_writes1));
6526 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6527 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076528 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6529 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246530
Bence Béky83eb3512017-09-05 12:56:096531 SSLSocketDataProvider ssl1(ASYNC, OK);
6532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6533 SSLSocketDataProvider ssl2(ASYNC, OK);
6534 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6535
[email protected]49639fa2011-12-20 23:22:416536 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246537
bnc691fda62016-08-12 00:43:166538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506539
tfarina42834112016-09-22 13:38:206540 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246542
6543 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016544 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246545
bnc691fda62016-08-12 00:43:166546 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226547
bnc691fda62016-08-12 00:43:166548 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526549 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046550 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246551
[email protected]49639fa2011-12-20 23:22:416552 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256553
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376554 rv = trans.RestartWithAuth(
6555 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6556 callback2.callback());
robpercival214763f2016-07-01 23:27:016557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256558
6559 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016560 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256561
bnc691fda62016-08-12 00:43:166562 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256563
bnc691fda62016-08-12 00:43:166564 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526565 ASSERT_TRUE(response);
6566 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256567
[email protected]49639fa2011-12-20 23:22:416568 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246569
bnc691fda62016-08-12 00:43:166570 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246572
[email protected]0757e7702009-03-27 04:00:226573 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016574 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246575
bnc691fda62016-08-12 00:43:166576 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526577 ASSERT_TRUE(response);
6578 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026579 EXPECT_EQ(14, response->headers->GetContentLength());
6580
6581 std::string response_data;
6582 rv = ReadTransaction(&trans, &response_data);
6583 EXPECT_THAT(rv, IsOk());
6584 EXPECT_EQ("Please Login\r\n", response_data);
6585
6586 EXPECT_TRUE(data1.AllReadDataConsumed());
6587 EXPECT_TRUE(data1.AllWriteDataConsumed());
6588 EXPECT_TRUE(data2.AllReadDataConsumed());
6589 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246590}
6591
[email protected]385a4672009-03-11 22:21:296592// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556593TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426594 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296595 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556596 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106597 request.traffic_annotation =
6598 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296599
Zentaro Kavanagh6ccee512017-09-28 18:34:096600 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6601 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276603
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376604 // Generate the NTLM messages based on known test data.
6605 std::string negotiate_msg;
6606 std::string challenge_msg;
6607 std::string authenticate_msg;
6608 base::Base64Encode(
6609 base::StringPiece(
6610 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6611 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6612 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556613 base::Base64Encode(
6614 base::StringPiece(
6615 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6616 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6617 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376618 base::Base64Encode(
6619 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096620 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556621 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6622 arraysize(
6623 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376624 &authenticate_msg);
6625
6626 // The authenticate message when |kWrongPassword| is sent.
6627 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556628 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6629 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6630 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6631 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6632 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6633 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376634
Zentaro Kavanagh1890a3d2018-01-29 19:52:556635 // Sanity check that it's the same length as the correct authenticate message
6636 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376637 ASSERT_EQ(authenticate_msg.length(),
6638 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556639 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376640
[email protected]385a4672009-03-11 22:21:296641 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556642 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6643 "Host: server\r\n"
6644 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296645 };
6646
6647 MockRead data_reads1[] = {
6648 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046649 // Negotiate and NTLM are often requested together. However, we only want
6650 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6651 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296652 MockRead("WWW-Authenticate: NTLM\r\n"),
6653 MockRead("Connection: close\r\n"),
6654 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366655 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296656 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296657 };
6658
6659 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166660 // After restarting with a null identity, this is the
6661 // request we should be issuing -- the final header line contains a Type
6662 // 1 message.
6663 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556664 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166665 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376666 "Authorization: NTLM "),
6667 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296668
bnc691fda62016-08-12 00:43:166669 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376670 // (using incorrect credentials). The second request continues on the
6671 // same connection.
bnc691fda62016-08-12 00:43:166672 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556673 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166674 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376675 "Authorization: NTLM "),
6676 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296677 };
6678
6679 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376680 // The origin server responds with a Type 2 message.
6681 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6682 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6683 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6684 MockRead("Content-Type: text/html\r\n\r\n"),
6685 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296686
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376687 // Wrong password.
6688 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6689 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6690 MockRead("Content-Length: 42\r\n"),
6691 MockRead("Content-Type: text/html\r\n\r\n"),
6692 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296693 };
6694
6695 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166696 // After restarting with a null identity, this is the
6697 // request we should be issuing -- the final header line contains a Type
6698 // 1 message.
6699 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556700 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166701 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376702 "Authorization: NTLM "),
6703 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296704
bnc691fda62016-08-12 00:43:166705 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6706 // (the credentials for the origin server). The second request continues
6707 // on the same connection.
6708 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556709 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166710 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376711 "Authorization: NTLM "),
6712 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296713 };
6714
6715 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026716 // The origin server responds with a Type 2 message.
6717 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376718 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6719 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026720 MockRead("Content-Type: text/html\r\n\r\n"),
6721 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296722
Bence Béky1e4ef192017-09-18 19:58:026723 // Lastly we get the desired content.
6724 MockRead("HTTP/1.1 200 OK\r\n"),
6725 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6726 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296727 };
6728
[email protected]31a2bfe2010-02-09 08:03:396729 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6730 data_writes1, arraysize(data_writes1));
6731 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6732 data_writes2, arraysize(data_writes2));
6733 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6734 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076735 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6736 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6737 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296738
Bence Béky83eb3512017-09-05 12:56:096739 SSLSocketDataProvider ssl1(ASYNC, OK);
6740 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6741 SSLSocketDataProvider ssl2(ASYNC, OK);
6742 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6743 SSLSocketDataProvider ssl3(ASYNC, OK);
6744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6745
[email protected]49639fa2011-12-20 23:22:416746 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296747
bnc691fda62016-08-12 00:43:166748 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506749
tfarina42834112016-09-22 13:38:206750 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296752
6753 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016754 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296755
bnc691fda62016-08-12 00:43:166756 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296757
bnc691fda62016-08-12 00:43:166758 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526759 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046760 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296761
[email protected]49639fa2011-12-20 23:22:416762 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296763
[email protected]0757e7702009-03-27 04:00:226764 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376765 rv = trans.RestartWithAuth(
6766 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6767 callback2.callback());
robpercival214763f2016-07-01 23:27:016768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296769
[email protected]10af5fe72011-01-31 16:17:256770 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016771 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296772
bnc691fda62016-08-12 00:43:166773 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416774 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166775 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256777 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016778 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166779 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226780
bnc691fda62016-08-12 00:43:166781 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526782 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046783 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226784
[email protected]49639fa2011-12-20 23:22:416785 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226786
6787 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376788 rv = trans.RestartWithAuth(
6789 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6790 callback4.callback());
robpercival214763f2016-07-01 23:27:016791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256792
6793 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016794 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256795
bnc691fda62016-08-12 00:43:166796 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256797
[email protected]49639fa2011-12-20 23:22:416798 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256799
6800 // One more roundtrip
bnc691fda62016-08-12 00:43:166801 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226803
6804 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016805 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226806
bnc691fda62016-08-12 00:43:166807 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526808 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026809 EXPECT_EQ(14, response->headers->GetContentLength());
6810
6811 std::string response_data;
6812 rv = ReadTransaction(&trans, &response_data);
6813 EXPECT_THAT(rv, IsOk());
6814 EXPECT_EQ("Please Login\r\n", response_data);
6815
6816 EXPECT_TRUE(data1.AllReadDataConsumed());
6817 EXPECT_TRUE(data1.AllWriteDataConsumed());
6818 EXPECT_TRUE(data2.AllReadDataConsumed());
6819 EXPECT_TRUE(data2.AllWriteDataConsumed());
6820 EXPECT_TRUE(data3.AllReadDataConsumed());
6821 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296822}
Bence Béky83eb3512017-09-05 12:56:096823
Bence Béky3238f2e12017-09-22 22:44:496824// Server requests NTLM authentication, which is not supported over HTTP/2.
6825// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096826TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096827 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6828 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096829
Zentaro Kavanagh1890a3d2018-01-29 19:52:556830 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096831
6832 HttpRequestInfo request;
6833 request.method = "GET";
6834 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:106835 request.traffic_annotation =
6836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096837
6838 // First request without credentials.
6839 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6840 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6841 1, std::move(request_headers0), LOWEST, true));
6842
6843 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276844 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096845 response_headers0["www-authenticate"] = "NTLM";
6846 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6847 1, std::move(response_headers0), true));
6848
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376849 // Stream 1 is closed.
6850 spdy_util_.UpdateWithStreamDestruction(1);
6851
6852 // Generate the NTLM messages based on known test data.
6853 std::string negotiate_msg;
6854 std::string challenge_msg;
6855 std::string authenticate_msg;
6856 base::Base64Encode(
6857 base::StringPiece(
6858 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6859 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6860 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556861 base::Base64Encode(
6862 base::StringPiece(
6863 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6864 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6865 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376866 base::Base64Encode(
6867 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096868 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556869 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6870 arraysize(
6871 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376872 &authenticate_msg);
6873
6874 // Retry with authorization header.
6875 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6876 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6877 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6878 3, std::move(request_headers1), LOWEST, true));
6879
6880 SpdySerializedFrame rst(
6881 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6882
Bence Béky3238f2e12017-09-22 22:44:496883 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6884 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096885
6886 // Retry yet again using HTTP/1.1.
6887 MockWrite writes1[] = {
6888 // After restarting with a null identity, this is the
6889 // request we should be issuing -- the final header line contains a Type
6890 // 1 message.
6891 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556892 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096893 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376894 "Authorization: NTLM "),
6895 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096896
6897 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6898 // (the credentials for the origin server). The second request continues
6899 // on the same connection.
6900 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556901 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096902 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376903 "Authorization: NTLM "),
6904 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096905 };
6906
6907 MockRead reads1[] = {
6908 // The origin server responds with a Type 2 message.
6909 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376910 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6911 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096912 MockRead("Content-Type: text/html\r\n\r\n"),
6913 MockRead("You are not authorized to view this page\r\n"),
6914
6915 // Lastly we get the desired content.
6916 MockRead("HTTP/1.1 200 OK\r\n"),
6917 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026918 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096919 };
6920 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6921 arraysize(writes0));
6922 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6923 arraysize(writes1));
6924 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6925 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6926
6927 SSLSocketDataProvider ssl0(ASYNC, OK);
6928 ssl0.next_proto = kProtoHTTP2;
6929 SSLSocketDataProvider ssl1(ASYNC, OK);
6930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6931 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6932
6933 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6934 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6935
6936 TestCompletionCallback callback1;
6937 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6939
6940 rv = callback1.WaitForResult();
6941 EXPECT_THAT(rv, IsOk());
6942
6943 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6944
6945 const HttpResponseInfo* response = trans.GetResponseInfo();
6946 ASSERT_TRUE(response);
6947 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6948
6949 TestCompletionCallback callback2;
6950
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376951 rv = trans.RestartWithAuth(
6952 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6953 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6955
6956 rv = callback2.WaitForResult();
6957 EXPECT_THAT(rv, IsOk());
6958
6959 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6960
6961 response = trans.GetResponseInfo();
6962 ASSERT_TRUE(response);
6963 EXPECT_FALSE(response->auth_challenge);
6964
6965 TestCompletionCallback callback3;
6966
6967 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6969
6970 rv = callback3.WaitForResult();
6971 EXPECT_THAT(rv, IsOk());
6972
6973 response = trans.GetResponseInfo();
6974 ASSERT_TRUE(response);
6975 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026976 EXPECT_EQ(14, response->headers->GetContentLength());
6977
6978 std::string response_data;
6979 rv = ReadTransaction(&trans, &response_data);
6980 EXPECT_THAT(rv, IsOk());
6981 EXPECT_EQ("Please Login\r\n", response_data);
6982
6983 EXPECT_TRUE(data0.AllReadDataConsumed());
6984 EXPECT_TRUE(data0.AllWriteDataConsumed());
6985 EXPECT_TRUE(data1.AllReadDataConsumed());
6986 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096987}
[email protected]ea9dc9a2009-09-05 00:43:326988#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296989
[email protected]4ddaf2502008-10-23 18:26:196990// Test reading a server response which has only headers, and no body.
6991// After some maximum number of bytes is consumed, the transaction should
6992// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016993TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426994 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196995 request.method = "GET";
bncce36dca22015-04-21 22:11:236996 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106997 request.traffic_annotation =
6998 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196999
danakj1fd259a02016-04-16 03:17:097000 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167001 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277002
[email protected]b75b7b2f2009-10-06 00:54:537003 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437004 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537005 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197006
7007 MockRead data_reads[] = {
7008 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067009 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197010 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067011 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197012 };
[email protected]31a2bfe2010-02-09 08:03:397013 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077014 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197015
[email protected]49639fa2011-12-20 23:22:417016 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197017
tfarina42834112016-09-22 13:38:207018 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197020
7021 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017022 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197023}
[email protected]f4e426b2008-11-05 00:24:497024
7025// Make sure that we don't try to reuse a TCPClientSocket when failing to
7026// establish tunnel.
7027// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017028TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277029 HttpRequestInfo request;
7030 request.method = "GET";
bncce36dca22015-04-21 22:11:237031 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107032 request.traffic_annotation =
7033 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277034
[email protected]f4e426b2008-11-05 00:24:497035 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497036 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7037 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017038
danakj1fd259a02016-04-16 03:17:097039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497040
bnc87dcefc2017-05-25 12:47:587041 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197042 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497043
[email protected]f4e426b2008-11-05 00:24:497044 // Since we have proxy, should try to establish tunnel.
7045 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177046 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7047 "Host: www.example.org:443\r\n"
7048 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497049 };
7050
[email protected]77848d12008-11-14 00:00:227051 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497052 // connection. Usually a proxy would return 501 (not implemented),
7053 // or 200 (tunnel established).
7054 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237055 MockRead("HTTP/1.1 404 Not Found\r\n"),
7056 MockRead("Content-Length: 10\r\n\r\n"),
7057 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497058 };
7059
[email protected]31a2bfe2010-02-09 08:03:397060 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7061 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077062 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497063
[email protected]49639fa2011-12-20 23:22:417064 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497065
tfarina42834112016-09-22 13:38:207066 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497068
7069 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017070 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497071
[email protected]b4404c02009-04-10 16:38:527072 // Empty the current queue. This is necessary because idle sockets are
7073 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557074 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527075
[email protected]f4e426b2008-11-05 00:24:497076 // We now check to make sure the TCPClientSocket was not added back to
7077 // the pool.
[email protected]90499482013-06-01 00:39:507078 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497079 trans.reset();
fdoray92e35a72016-06-10 15:54:557080 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497081 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507082 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497083}
[email protected]372d34a2008-11-05 21:30:517084
[email protected]1b157c02009-04-21 01:55:407085// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017086TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427087 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407088 request.method = "GET";
bncce36dca22015-04-21 22:11:237089 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107090 request.traffic_annotation =
7091 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407092
danakj1fd259a02016-04-16 03:17:097093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277094
bnc691fda62016-08-12 00:43:167095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277096
[email protected]1b157c02009-04-21 01:55:407097 MockRead data_reads[] = {
7098 // A part of the response body is received with the response headers.
7099 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7100 // The rest of the response body is received in two parts.
7101 MockRead("lo"),
7102 MockRead(" world"),
7103 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067104 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407105 };
7106
[email protected]31a2bfe2010-02-09 08:03:397107 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077108 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407109
[email protected]49639fa2011-12-20 23:22:417110 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407111
tfarina42834112016-09-22 13:38:207112 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407114
7115 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017116 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407117
bnc691fda62016-08-12 00:43:167118 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527119 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407120
wezca1070932016-05-26 20:30:527121 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407122 std::string status_line = response->headers->GetStatusLine();
7123 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7124
[email protected]90499482013-06-01 00:39:507125 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407126
7127 std::string response_data;
bnc691fda62016-08-12 00:43:167128 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017129 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407130 EXPECT_EQ("hello world", response_data);
7131
7132 // Empty the current queue. This is necessary because idle sockets are
7133 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557134 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407135
7136 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507137 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407138}
7139
[email protected]76a505b2010-08-25 06:23:007140// Make sure that we recycle a SSL socket after reading all of the response
7141// body.
bncd16676a2016-07-20 16:23:017142TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007143 HttpRequestInfo request;
7144 request.method = "GET";
bncce36dca22015-04-21 22:11:237145 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107146 request.traffic_annotation =
7147 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007148
7149 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237150 MockWrite(
7151 "GET / HTTP/1.1\r\n"
7152 "Host: www.example.org\r\n"
7153 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007154 };
7155
7156 MockRead data_reads[] = {
7157 MockRead("HTTP/1.1 200 OK\r\n"),
7158 MockRead("Content-Length: 11\r\n\r\n"),
7159 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067160 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007161 };
7162
[email protected]8ddf8322012-02-23 18:08:067163 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007165
7166 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7167 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077168 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007169
[email protected]49639fa2011-12-20 23:22:417170 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007171
danakj1fd259a02016-04-16 03:17:097172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007174
tfarina42834112016-09-22 13:38:207175 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007176
robpercival214763f2016-07-01 23:27:017177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7178 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007179
bnc691fda62016-08-12 00:43:167180 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527181 ASSERT_TRUE(response);
7182 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007183 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7184
[email protected]90499482013-06-01 00:39:507185 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007186
7187 std::string response_data;
bnc691fda62016-08-12 00:43:167188 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017189 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007190 EXPECT_EQ("hello world", response_data);
7191
7192 // Empty the current queue. This is necessary because idle sockets are
7193 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557194 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007195
7196 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507197 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007198}
7199
7200// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7201// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017202TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007203 HttpRequestInfo request;
7204 request.method = "GET";
bncce36dca22015-04-21 22:11:237205 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107206 request.traffic_annotation =
7207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007208
7209 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237210 MockWrite(
7211 "GET / HTTP/1.1\r\n"
7212 "Host: www.example.org\r\n"
7213 "Connection: keep-alive\r\n\r\n"),
7214 MockWrite(
7215 "GET / HTTP/1.1\r\n"
7216 "Host: www.example.org\r\n"
7217 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007218 };
7219
7220 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427221 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7222 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007223
[email protected]8ddf8322012-02-23 18:08:067224 SSLSocketDataProvider ssl(ASYNC, OK);
7225 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007228
7229 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7230 data_writes, arraysize(data_writes));
7231 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7232 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077233 session_deps_.socket_factory->AddSocketDataProvider(&data);
7234 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007235
[email protected]49639fa2011-12-20 23:22:417236 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007237
danakj1fd259a02016-04-16 03:17:097238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587239 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197240 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007241
tfarina42834112016-09-22 13:38:207242 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007243
robpercival214763f2016-07-01 23:27:017244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7245 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007246
7247 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527248 ASSERT_TRUE(response);
7249 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007250 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7251
[email protected]90499482013-06-01 00:39:507252 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007253
7254 std::string response_data;
7255 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017256 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007257 EXPECT_EQ("hello world", response_data);
7258
7259 // Empty the current queue. This is necessary because idle sockets are
7260 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557261 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007262
7263 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507264 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007265
7266 // Now start the second transaction, which should reuse the previous socket.
7267
bnc87dcefc2017-05-25 12:47:587268 trans =
Jeremy Roman0579ed62017-08-29 15:56:197269 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007270
tfarina42834112016-09-22 13:38:207271 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007272
robpercival214763f2016-07-01 23:27:017273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7274 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007275
7276 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527277 ASSERT_TRUE(response);
7278 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007279 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7280
[email protected]90499482013-06-01 00:39:507281 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007282
7283 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017284 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007285 EXPECT_EQ("hello world", response_data);
7286
7287 // Empty the current queue. This is necessary because idle sockets are
7288 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557289 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007290
7291 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507292 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007293}
7294
maksim.sisov0adf8592016-07-15 06:25:567295// Grab a socket, use it, and put it back into the pool. Then, make
7296// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017297TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567298 HttpRequestInfo request;
7299 request.method = "GET";
7300 request.url = GURL("http://www.example.org/");
7301 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107302 request.traffic_annotation =
7303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567304
7305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7306
bnc691fda62016-08-12 00:43:167307 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567308
7309 MockRead data_reads[] = {
7310 // A part of the response body is received with the response headers.
7311 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7312 // The rest of the response body is received in two parts.
7313 MockRead("lo"), MockRead(" world"),
7314 MockRead("junk"), // Should not be read!!
7315 MockRead(SYNCHRONOUS, OK),
7316 };
7317
7318 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7319 session_deps_.socket_factory->AddSocketDataProvider(&data);
7320
7321 TestCompletionCallback callback;
7322
tfarina42834112016-09-22 13:38:207323 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7325
7326 EXPECT_THAT(callback.GetResult(rv), IsOk());
7327
bnc691fda62016-08-12 00:43:167328 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567329 ASSERT_TRUE(response);
7330 EXPECT_TRUE(response->headers);
7331 std::string status_line = response->headers->GetStatusLine();
7332 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7333
7334 // Make memory critical notification and ensure the transaction still has been
7335 // operating right.
7336 base::MemoryPressureListener::NotifyMemoryPressure(
7337 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7338 base::RunLoop().RunUntilIdle();
7339
7340 // Socket should not be flushed as long as it is not idle.
7341 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7342
7343 std::string response_data;
bnc691fda62016-08-12 00:43:167344 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567345 EXPECT_THAT(rv, IsOk());
7346 EXPECT_EQ("hello world", response_data);
7347
7348 // Empty the current queue. This is necessary because idle sockets are
7349 // added to the connection pool asynchronously with a PostTask.
7350 base::RunLoop().RunUntilIdle();
7351
7352 // We now check to make sure the socket was added back to the pool.
7353 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7354
7355 // Idle sockets should be flushed now.
7356 base::MemoryPressureListener::NotifyMemoryPressure(
7357 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7358 base::RunLoop().RunUntilIdle();
7359
7360 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7361}
7362
yucliu48f235d2018-01-11 00:59:557363// Disable idle socket closing on memory pressure.
7364// Grab a socket, use it, and put it back into the pool. Then, make
7365// low memory notification and ensure the socket pool is NOT flushed.
7366TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7367 HttpRequestInfo request;
7368 request.method = "GET";
7369 request.url = GURL("http://www.example.org/");
7370 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107371 request.traffic_annotation =
7372 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557373
7374 // Disable idle socket closing on memory pressure.
7375 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7377
7378 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7379
7380 MockRead data_reads[] = {
7381 // A part of the response body is received with the response headers.
7382 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7383 // The rest of the response body is received in two parts.
7384 MockRead("lo"), MockRead(" world"),
7385 MockRead("junk"), // Should not be read!!
7386 MockRead(SYNCHRONOUS, OK),
7387 };
7388
7389 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7390 session_deps_.socket_factory->AddSocketDataProvider(&data);
7391
7392 TestCompletionCallback callback;
7393
7394 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7395 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7396
7397 EXPECT_THAT(callback.GetResult(rv), IsOk());
7398
7399 const HttpResponseInfo* response = trans.GetResponseInfo();
7400 ASSERT_TRUE(response);
7401 EXPECT_TRUE(response->headers);
7402 std::string status_line = response->headers->GetStatusLine();
7403 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7404
7405 // Make memory critical notification and ensure the transaction still has been
7406 // operating right.
7407 base::MemoryPressureListener::NotifyMemoryPressure(
7408 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7409 base::RunLoop().RunUntilIdle();
7410
7411 // Socket should not be flushed as long as it is not idle.
7412 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7413
7414 std::string response_data;
7415 rv = ReadTransaction(&trans, &response_data);
7416 EXPECT_THAT(rv, IsOk());
7417 EXPECT_EQ("hello world", response_data);
7418
7419 // Empty the current queue. This is necessary because idle sockets are
7420 // added to the connection pool asynchronously with a PostTask.
7421 base::RunLoop().RunUntilIdle();
7422
7423 // We now check to make sure the socket was added back to the pool.
7424 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7425
7426 // Idle sockets should NOT be flushed on moderate memory pressure.
7427 base::MemoryPressureListener::NotifyMemoryPressure(
7428 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7429 base::RunLoop().RunUntilIdle();
7430
7431 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7432
7433 // Idle sockets should NOT be flushed on critical memory pressure.
7434 base::MemoryPressureListener::NotifyMemoryPressure(
7435 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7436 base::RunLoop().RunUntilIdle();
7437
7438 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7439}
7440
maksim.sisov0adf8592016-07-15 06:25:567441// Grab an SSL socket, use it, and put it back into the pool. Then, make
7442// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017443TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567444 HttpRequestInfo request;
7445 request.method = "GET";
7446 request.url = GURL("https://www.example.org/");
7447 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107448 request.traffic_annotation =
7449 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567450
7451 MockWrite data_writes[] = {
7452 MockWrite("GET / HTTP/1.1\r\n"
7453 "Host: www.example.org\r\n"
7454 "Connection: keep-alive\r\n\r\n"),
7455 };
7456
7457 MockRead data_reads[] = {
7458 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7459 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7460
7461 SSLSocketDataProvider ssl(ASYNC, OK);
7462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7463
7464 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7465 arraysize(data_writes));
7466 session_deps_.socket_factory->AddSocketDataProvider(&data);
7467
7468 TestCompletionCallback callback;
7469
7470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567472
7473 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207474 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567475
7476 EXPECT_THAT(callback.GetResult(rv), IsOk());
7477
bnc691fda62016-08-12 00:43:167478 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567479 ASSERT_TRUE(response);
7480 ASSERT_TRUE(response->headers);
7481 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7482
7483 // Make memory critical notification and ensure the transaction still has been
7484 // operating right.
7485 base::MemoryPressureListener::NotifyMemoryPressure(
7486 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7487 base::RunLoop().RunUntilIdle();
7488
7489 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7490
7491 std::string response_data;
bnc691fda62016-08-12 00:43:167492 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567493 EXPECT_THAT(rv, IsOk());
7494 EXPECT_EQ("hello world", response_data);
7495
7496 // Empty the current queue. This is necessary because idle sockets are
7497 // added to the connection pool asynchronously with a PostTask.
7498 base::RunLoop().RunUntilIdle();
7499
7500 // We now check to make sure the socket was added back to the pool.
7501 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7502
7503 // Make memory notification once again and ensure idle socket is closed.
7504 base::MemoryPressureListener::NotifyMemoryPressure(
7505 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7506 base::RunLoop().RunUntilIdle();
7507
7508 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7509}
7510
[email protected]b4404c02009-04-10 16:38:527511// Make sure that we recycle a socket after a zero-length response.
7512// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017513TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427514 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527515 request.method = "GET";
bncce36dca22015-04-21 22:11:237516 request.url = GURL(
7517 "http://www.example.org/csi?v=3&s=web&action=&"
7518 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7519 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7520 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:107521 request.traffic_annotation =
7522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527523
danakj1fd259a02016-04-16 03:17:097524 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277525
[email protected]b4404c02009-04-10 16:38:527526 MockRead data_reads[] = {
7527 MockRead("HTTP/1.1 204 No Content\r\n"
7528 "Content-Length: 0\r\n"
7529 "Content-Type: text/html\r\n\r\n"),
7530 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067531 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527532 };
7533
[email protected]31a2bfe2010-02-09 08:03:397534 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077535 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527536
mmenkecc2298e2015-12-07 18:20:187537 // Transaction must be created after the MockReads, so it's destroyed before
7538 // them.
bnc691fda62016-08-12 00:43:167539 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187540
[email protected]49639fa2011-12-20 23:22:417541 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527542
tfarina42834112016-09-22 13:38:207543 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527545
7546 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017547 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527548
bnc691fda62016-08-12 00:43:167549 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527550 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527551
wezca1070932016-05-26 20:30:527552 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527553 std::string status_line = response->headers->GetStatusLine();
7554 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7555
[email protected]90499482013-06-01 00:39:507556 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527557
7558 std::string response_data;
bnc691fda62016-08-12 00:43:167559 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017560 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527561 EXPECT_EQ("", response_data);
7562
7563 // Empty the current queue. This is necessary because idle sockets are
7564 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557565 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527566
7567 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507568 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527569}
7570
bncd16676a2016-07-20 16:23:017571TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097572 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227573 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197574 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227575 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277576
[email protected]1c773ea12009-04-28 19:58:427577 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517578 // Transaction 1: a GET request that succeeds. The socket is recycled
7579 // after use.
7580 request[0].method = "GET";
7581 request[0].url = GURL("http://www.google.com/");
7582 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107583 request[0].traffic_annotation =
7584 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517585 // Transaction 2: a POST request. Reuses the socket kept alive from
7586 // transaction 1. The first attempts fails when writing the POST data.
7587 // This causes the transaction to retry with a new socket. The second
7588 // attempt succeeds.
7589 request[1].method = "POST";
7590 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277591 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517592 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107593 request[1].traffic_annotation =
7594 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517595
danakj1fd259a02016-04-16 03:17:097596 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517597
7598 // The first socket is used for transaction 1 and the first attempt of
7599 // transaction 2.
7600
7601 // The response of transaction 1.
7602 MockRead data_reads1[] = {
7603 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7604 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067605 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517606 };
7607 // The mock write results of transaction 1 and the first attempt of
7608 // transaction 2.
7609 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067610 MockWrite(SYNCHRONOUS, 64), // GET
7611 MockWrite(SYNCHRONOUS, 93), // POST
7612 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517613 };
[email protected]31a2bfe2010-02-09 08:03:397614 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7615 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517616
7617 // The second socket is used for the second attempt of transaction 2.
7618
7619 // The response of transaction 2.
7620 MockRead data_reads2[] = {
7621 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7622 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067623 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517624 };
7625 // The mock write results of the second attempt of transaction 2.
7626 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067627 MockWrite(SYNCHRONOUS, 93), // POST
7628 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517629 };
[email protected]31a2bfe2010-02-09 08:03:397630 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7631 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517632
[email protected]bb88e1d32013-05-03 23:11:077633 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7634 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517635
thestig9d3bb0c2015-01-24 00:49:517636 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517637 "hello world", "welcome"
7638 };
7639
7640 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517642
[email protected]49639fa2011-12-20 23:22:417643 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517644
tfarina42834112016-09-22 13:38:207645 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517647
7648 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017649 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517650
bnc691fda62016-08-12 00:43:167651 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527652 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517653
wezca1070932016-05-26 20:30:527654 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517655 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7656
7657 std::string response_data;
bnc691fda62016-08-12 00:43:167658 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017659 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517660 EXPECT_EQ(kExpectedResponseData[i], response_data);
7661 }
7662}
[email protected]f9ee6b52008-11-08 06:46:237663
7664// Test the request-challenge-retry sequence for basic auth when there is
7665// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167666// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017667TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427668 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237669 request.method = "GET";
bncce36dca22015-04-21 22:11:237670 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417671 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107672 request.traffic_annotation =
7673 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297674
danakj1fd259a02016-04-16 03:17:097675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277677
[email protected]a97cca42009-08-14 01:00:297678 // The password contains an escaped character -- for this test to pass it
7679 // will need to be unescaped by HttpNetworkTransaction.
7680 EXPECT_EQ("b%40r", request.url.password());
7681
[email protected]f9ee6b52008-11-08 06:46:237682 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237683 MockWrite(
7684 "GET / HTTP/1.1\r\n"
7685 "Host: www.example.org\r\n"
7686 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237687 };
7688
7689 MockRead data_reads1[] = {
7690 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7691 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7692 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067693 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237694 };
7695
[email protected]2262e3a2012-05-22 16:08:167696 // After the challenge above, the transaction will be restarted using the
7697 // identity from the url (foo, b@r) to answer the challenge.
7698 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237699 MockWrite(
7700 "GET / HTTP/1.1\r\n"
7701 "Host: www.example.org\r\n"
7702 "Connection: keep-alive\r\n"
7703 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167704 };
7705
7706 MockRead data_reads2[] = {
7707 MockRead("HTTP/1.0 200 OK\r\n"),
7708 MockRead("Content-Length: 100\r\n\r\n"),
7709 MockRead(SYNCHRONOUS, OK),
7710 };
7711
[email protected]31a2bfe2010-02-09 08:03:397712 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7713 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167714 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7715 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077716 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7717 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237718
[email protected]49639fa2011-12-20 23:22:417719 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207720 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237722 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017723 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167724 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167725
7726 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167727 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167729 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017730 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167731 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227732
bnc691fda62016-08-12 00:43:167733 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527734 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167735
7736 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527737 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167738
7739 EXPECT_EQ(100, response->headers->GetContentLength());
7740
7741 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557742 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167743}
7744
7745// Test the request-challenge-retry sequence for basic auth when there is an
7746// incorrect identity in the URL. The identity from the URL should be used only
7747// once.
bncd16676a2016-07-20 16:23:017748TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167749 HttpRequestInfo request;
7750 request.method = "GET";
7751 // Note: the URL has a username:password in it. The password "baz" is
7752 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237753 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167754
7755 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107756 request.traffic_annotation =
7757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167758
danakj1fd259a02016-04-16 03:17:097759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167761
7762 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237763 MockWrite(
7764 "GET / HTTP/1.1\r\n"
7765 "Host: www.example.org\r\n"
7766 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167767 };
7768
7769 MockRead data_reads1[] = {
7770 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7771 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7772 MockRead("Content-Length: 10\r\n\r\n"),
7773 MockRead(SYNCHRONOUS, ERR_FAILED),
7774 };
7775
7776 // After the challenge above, the transaction will be restarted using the
7777 // identity from the url (foo, baz) to answer the challenge.
7778 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237779 MockWrite(
7780 "GET / HTTP/1.1\r\n"
7781 "Host: www.example.org\r\n"
7782 "Connection: keep-alive\r\n"
7783 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167784 };
7785
7786 MockRead data_reads2[] = {
7787 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7788 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7789 MockRead("Content-Length: 10\r\n\r\n"),
7790 MockRead(SYNCHRONOUS, ERR_FAILED),
7791 };
7792
7793 // After the challenge above, the transaction will be restarted using the
7794 // identity supplied by the user (foo, bar) to answer the challenge.
7795 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237796 MockWrite(
7797 "GET / HTTP/1.1\r\n"
7798 "Host: www.example.org\r\n"
7799 "Connection: keep-alive\r\n"
7800 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167801 };
7802
7803 MockRead data_reads3[] = {
7804 MockRead("HTTP/1.0 200 OK\r\n"),
7805 MockRead("Content-Length: 100\r\n\r\n"),
7806 MockRead(SYNCHRONOUS, OK),
7807 };
7808
7809 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7810 data_writes1, arraysize(data_writes1));
7811 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7812 data_writes2, arraysize(data_writes2));
7813 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7814 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077815 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7816 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7817 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167818
7819 TestCompletionCallback callback1;
7820
tfarina42834112016-09-22 13:38:207821 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167823
7824 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017825 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167826
bnc691fda62016-08-12 00:43:167827 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167828 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167829 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167831 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017832 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167833 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167834
bnc691fda62016-08-12 00:43:167835 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527836 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167837 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7838
7839 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167840 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167842 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017843 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167844 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167845
bnc691fda62016-08-12 00:43:167846 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527847 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167848
7849 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527850 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167851
7852 EXPECT_EQ(100, response->headers->GetContentLength());
7853
[email protected]ea9dc9a2009-09-05 00:43:327854 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557855 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327856}
7857
[email protected]2217aa22013-10-11 03:03:547858
7859// Test the request-challenge-retry sequence for basic auth when there is a
7860// correct identity in the URL, but its use is being suppressed. The identity
7861// from the URL should never be used.
bncd16676a2016-07-20 16:23:017862TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547863 HttpRequestInfo request;
7864 request.method = "GET";
bncce36dca22015-04-21 22:11:237865 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547866 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:107867 request.traffic_annotation =
7868 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547869
danakj1fd259a02016-04-16 03:17:097870 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167871 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547872
7873 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237874 MockWrite(
7875 "GET / HTTP/1.1\r\n"
7876 "Host: www.example.org\r\n"
7877 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547878 };
7879
7880 MockRead data_reads1[] = {
7881 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7882 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7883 MockRead("Content-Length: 10\r\n\r\n"),
7884 MockRead(SYNCHRONOUS, ERR_FAILED),
7885 };
7886
7887 // After the challenge above, the transaction will be restarted using the
7888 // identity supplied by the user, not the one in the URL, to answer the
7889 // challenge.
7890 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237891 MockWrite(
7892 "GET / HTTP/1.1\r\n"
7893 "Host: www.example.org\r\n"
7894 "Connection: keep-alive\r\n"
7895 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547896 };
7897
7898 MockRead data_reads3[] = {
7899 MockRead("HTTP/1.0 200 OK\r\n"),
7900 MockRead("Content-Length: 100\r\n\r\n"),
7901 MockRead(SYNCHRONOUS, OK),
7902 };
7903
7904 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7905 data_writes1, arraysize(data_writes1));
7906 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7907 data_writes3, arraysize(data_writes3));
7908 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7909 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7910
7911 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207912 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547914 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017915 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167916 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547917
bnc691fda62016-08-12 00:43:167918 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527919 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547920 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7921
7922 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167923 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017924 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547925 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017926 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167927 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547928
bnc691fda62016-08-12 00:43:167929 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527930 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547931
7932 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527933 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547934 EXPECT_EQ(100, response->headers->GetContentLength());
7935
7936 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557937 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547938}
7939
[email protected]f9ee6b52008-11-08 06:46:237940// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017941TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237943
7944 // Transaction 1: authenticate (foo, bar) on MyRealm1
7945 {
[email protected]1c773ea12009-04-28 19:58:427946 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237947 request.method = "GET";
bncce36dca22015-04-21 22:11:237948 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:107949 request.traffic_annotation =
7950 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237951
bnc691fda62016-08-12 00:43:167952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277953
[email protected]f9ee6b52008-11-08 06:46:237954 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237955 MockWrite(
7956 "GET /x/y/z HTTP/1.1\r\n"
7957 "Host: www.example.org\r\n"
7958 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237959 };
7960
7961 MockRead data_reads1[] = {
7962 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7963 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\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 (username=foo, password=bar)
7969 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237970 MockWrite(
7971 "GET /x/y/z HTTP/1.1\r\n"
7972 "Host: www.example.org\r\n"
7973 "Connection: keep-alive\r\n"
7974 "Authorization: Basic Zm9vOmJhcg==\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);
[email protected]79cb5c12011-09-12 13:12:048001 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238002
[email protected]49639fa2011-12-20 23:22:418003 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238004
bnc691fda62016-08-12 00:43:168005 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8006 callback2.callback());
robpercival214763f2016-07-01 23:27:018007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238008
8009 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018010 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238011
bnc691fda62016-08-12 00:43:168012 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528013 ASSERT_TRUE(response);
8014 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238015 EXPECT_EQ(100, response->headers->GetContentLength());
8016 }
8017
8018 // ------------------------------------------------------------------------
8019
8020 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8021 {
[email protected]1c773ea12009-04-28 19:58:428022 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238023 request.method = "GET";
8024 // Note that Transaction 1 was at /x/y/z, so this is in the same
8025 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238026 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108027 request.traffic_annotation =
8028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238029
bnc691fda62016-08-12 00:43:168030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278031
[email protected]f9ee6b52008-11-08 06:46:238032 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238033 MockWrite(
8034 "GET /x/y/a/b HTTP/1.1\r\n"
8035 "Host: www.example.org\r\n"
8036 "Connection: keep-alive\r\n"
8037 // Send preemptive authorization for MyRealm1
8038 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238039 };
8040
8041 // The server didn't like the preemptive authorization, and
8042 // challenges us for a different realm (MyRealm2).
8043 MockRead data_reads1[] = {
8044 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8045 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8046 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068047 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238048 };
8049
8050 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8051 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238052 MockWrite(
8053 "GET /x/y/a/b HTTP/1.1\r\n"
8054 "Host: www.example.org\r\n"
8055 "Connection: keep-alive\r\n"
8056 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238057 };
8058
8059 // Sever accepts the authorization.
8060 MockRead data_reads2[] = {
8061 MockRead("HTTP/1.0 200 OK\r\n"),
8062 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068063 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238064 };
8065
[email protected]31a2bfe2010-02-09 08:03:398066 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8067 data_writes1, arraysize(data_writes1));
8068 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8069 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078070 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8071 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238072
[email protected]49639fa2011-12-20 23:22:418073 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238074
tfarina42834112016-09-22 13:38:208075 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238077
8078 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018079 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238080
bnc691fda62016-08-12 00:43:168081 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528082 ASSERT_TRUE(response);
8083 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048084 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438085 EXPECT_EQ("http://www.example.org",
8086 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048087 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198088 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238089
[email protected]49639fa2011-12-20 23:22:418090 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238091
bnc691fda62016-08-12 00:43:168092 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8093 callback2.callback());
robpercival214763f2016-07-01 23:27:018094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238095
8096 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018097 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238098
bnc691fda62016-08-12 00:43:168099 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528100 ASSERT_TRUE(response);
8101 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238102 EXPECT_EQ(100, response->headers->GetContentLength());
8103 }
8104
8105 // ------------------------------------------------------------------------
8106
8107 // Transaction 3: Resend a request in MyRealm's protection space --
8108 // succeed with preemptive authorization.
8109 {
[email protected]1c773ea12009-04-28 19:58:428110 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238111 request.method = "GET";
bncce36dca22015-04-21 22:11:238112 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108113 request.traffic_annotation =
8114 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238115
bnc691fda62016-08-12 00:43:168116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278117
[email protected]f9ee6b52008-11-08 06:46:238118 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238119 MockWrite(
8120 "GET /x/y/z2 HTTP/1.1\r\n"
8121 "Host: www.example.org\r\n"
8122 "Connection: keep-alive\r\n"
8123 // The authorization for MyRealm1 gets sent preemptively
8124 // (since the url is in the same protection space)
8125 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238126 };
8127
8128 // Sever accepts the preemptive authorization
8129 MockRead data_reads1[] = {
8130 MockRead("HTTP/1.0 200 OK\r\n"),
8131 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068132 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238133 };
8134
[email protected]31a2bfe2010-02-09 08:03:398135 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8136 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078137 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238138
[email protected]49639fa2011-12-20 23:22:418139 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238140
tfarina42834112016-09-22 13:38:208141 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238143
8144 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018145 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238146
bnc691fda62016-08-12 00:43:168147 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528148 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238149
wezca1070932016-05-26 20:30:528150 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238151 EXPECT_EQ(100, response->headers->GetContentLength());
8152 }
8153
8154 // ------------------------------------------------------------------------
8155
8156 // Transaction 4: request another URL in MyRealm (however the
8157 // url is not known to belong to the protection space, so no pre-auth).
8158 {
[email protected]1c773ea12009-04-28 19:58:428159 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238160 request.method = "GET";
bncce36dca22015-04-21 22:11:238161 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108162 request.traffic_annotation =
8163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238164
bnc691fda62016-08-12 00:43:168165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278166
[email protected]f9ee6b52008-11-08 06:46:238167 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238168 MockWrite(
8169 "GET /x/1 HTTP/1.1\r\n"
8170 "Host: www.example.org\r\n"
8171 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238172 };
8173
8174 MockRead data_reads1[] = {
8175 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8176 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8177 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068178 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238179 };
8180
8181 // Resend with authorization from MyRealm's cache.
8182 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238183 MockWrite(
8184 "GET /x/1 HTTP/1.1\r\n"
8185 "Host: www.example.org\r\n"
8186 "Connection: keep-alive\r\n"
8187 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238188 };
8189
8190 // Sever accepts the authorization.
8191 MockRead data_reads2[] = {
8192 MockRead("HTTP/1.0 200 OK\r\n"),
8193 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068194 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238195 };
8196
[email protected]31a2bfe2010-02-09 08:03:398197 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8198 data_writes1, arraysize(data_writes1));
8199 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8200 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078201 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8202 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238203
[email protected]49639fa2011-12-20 23:22:418204 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238205
tfarina42834112016-09-22 13:38:208206 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238208
8209 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018210 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238211
bnc691fda62016-08-12 00:43:168212 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418213 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168214 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228216 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018217 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168218 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228219
bnc691fda62016-08-12 00:43:168220 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528221 ASSERT_TRUE(response);
8222 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238223 EXPECT_EQ(100, response->headers->GetContentLength());
8224 }
8225
8226 // ------------------------------------------------------------------------
8227
8228 // Transaction 5: request a URL in MyRealm, but the server rejects the
8229 // cached identity. Should invalidate and re-prompt.
8230 {
[email protected]1c773ea12009-04-28 19:58:428231 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238232 request.method = "GET";
bncce36dca22015-04-21 22:11:238233 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:108234 request.traffic_annotation =
8235 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238236
bnc691fda62016-08-12 00:43:168237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278238
[email protected]f9ee6b52008-11-08 06:46:238239 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238240 MockWrite(
8241 "GET /p/q/t HTTP/1.1\r\n"
8242 "Host: www.example.org\r\n"
8243 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238244 };
8245
8246 MockRead data_reads1[] = {
8247 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8248 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8249 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068250 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238251 };
8252
8253 // Resend with authorization from cache for MyRealm.
8254 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238255 MockWrite(
8256 "GET /p/q/t HTTP/1.1\r\n"
8257 "Host: www.example.org\r\n"
8258 "Connection: keep-alive\r\n"
8259 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238260 };
8261
8262 // Sever rejects the authorization.
8263 MockRead data_reads2[] = {
8264 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8265 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8266 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068267 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238268 };
8269
8270 // At this point we should prompt for new credentials for MyRealm.
8271 // Restart with username=foo3, password=foo4.
8272 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238273 MockWrite(
8274 "GET /p/q/t HTTP/1.1\r\n"
8275 "Host: www.example.org\r\n"
8276 "Connection: keep-alive\r\n"
8277 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238278 };
8279
8280 // Sever accepts the authorization.
8281 MockRead data_reads3[] = {
8282 MockRead("HTTP/1.0 200 OK\r\n"),
8283 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068284 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238285 };
8286
[email protected]31a2bfe2010-02-09 08:03:398287 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8288 data_writes1, arraysize(data_writes1));
8289 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8290 data_writes2, arraysize(data_writes2));
8291 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8292 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078293 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8294 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8295 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238296
[email protected]49639fa2011-12-20 23:22:418297 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238298
tfarina42834112016-09-22 13:38:208299 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018300 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238301
8302 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018303 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238304
bnc691fda62016-08-12 00:43:168305 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418306 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168307 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228309 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018310 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168311 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228312
bnc691fda62016-08-12 00:43:168313 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528314 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048315 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238316
[email protected]49639fa2011-12-20 23:22:418317 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238318
bnc691fda62016-08-12 00:43:168319 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8320 callback3.callback());
robpercival214763f2016-07-01 23:27:018321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238322
[email protected]0757e7702009-03-27 04:00:228323 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018324 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238325
bnc691fda62016-08-12 00:43:168326 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528327 ASSERT_TRUE(response);
8328 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238329 EXPECT_EQ(100, response->headers->GetContentLength());
8330 }
8331}
[email protected]89ceba9a2009-03-21 03:46:068332
[email protected]3c32c5f2010-05-18 15:18:128333// Tests that nonce count increments when multiple auth attempts
8334// are started with the same nonce.
bncd16676a2016-07-20 16:23:018335TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448336 HttpAuthHandlerDigest::Factory* digest_factory =
8337 new HttpAuthHandlerDigest::Factory();
8338 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8339 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8340 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078341 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128343
8344 // Transaction 1: authenticate (foo, bar) on MyRealm1
8345 {
[email protected]3c32c5f2010-05-18 15:18:128346 HttpRequestInfo request;
8347 request.method = "GET";
bncce36dca22015-04-21 22:11:238348 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108349 request.traffic_annotation =
8350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128351
bnc691fda62016-08-12 00:43:168352 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278353
[email protected]3c32c5f2010-05-18 15:18:128354 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238355 MockWrite(
8356 "GET /x/y/z HTTP/1.1\r\n"
8357 "Host: www.example.org\r\n"
8358 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128359 };
8360
8361 MockRead data_reads1[] = {
8362 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8363 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8364 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068365 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128366 };
8367
8368 // Resend with authorization (username=foo, password=bar)
8369 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238370 MockWrite(
8371 "GET /x/y/z HTTP/1.1\r\n"
8372 "Host: www.example.org\r\n"
8373 "Connection: keep-alive\r\n"
8374 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8375 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8376 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8377 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128378 };
8379
8380 // Sever accepts the authorization.
8381 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088382 MockRead("HTTP/1.0 200 OK\r\n"),
8383 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128384 };
8385
8386 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8387 data_writes1, arraysize(data_writes1));
8388 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8389 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078390 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8391 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128392
[email protected]49639fa2011-12-20 23:22:418393 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128394
tfarina42834112016-09-22 13:38:208395 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128397
8398 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018399 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128400
bnc691fda62016-08-12 00:43:168401 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528402 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048403 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128404
[email protected]49639fa2011-12-20 23:22:418405 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128406
bnc691fda62016-08-12 00:43:168407 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8408 callback2.callback());
robpercival214763f2016-07-01 23:27:018409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128410
8411 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018412 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128413
bnc691fda62016-08-12 00:43:168414 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528415 ASSERT_TRUE(response);
8416 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128417 }
8418
8419 // ------------------------------------------------------------------------
8420
8421 // Transaction 2: Request another resource in digestive's protection space.
8422 // This will preemptively add an Authorization header which should have an
8423 // "nc" value of 2 (as compared to 1 in the first use.
8424 {
[email protected]3c32c5f2010-05-18 15:18:128425 HttpRequestInfo request;
8426 request.method = "GET";
8427 // Note that Transaction 1 was at /x/y/z, so this is in the same
8428 // protection space as digest.
bncce36dca22015-04-21 22:11:238429 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108430 request.traffic_annotation =
8431 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128432
bnc691fda62016-08-12 00:43:168433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278434
[email protected]3c32c5f2010-05-18 15:18:128435 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238436 MockWrite(
8437 "GET /x/y/a/b HTTP/1.1\r\n"
8438 "Host: www.example.org\r\n"
8439 "Connection: keep-alive\r\n"
8440 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8441 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8442 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8443 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128444 };
8445
8446 // Sever accepts the authorization.
8447 MockRead data_reads1[] = {
8448 MockRead("HTTP/1.0 200 OK\r\n"),
8449 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068450 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128451 };
8452
8453 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8454 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078455 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128456
[email protected]49639fa2011-12-20 23:22:418457 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128458
tfarina42834112016-09-22 13:38:208459 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128461
8462 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018463 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128464
bnc691fda62016-08-12 00:43:168465 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528466 ASSERT_TRUE(response);
8467 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128468 }
8469}
8470
[email protected]89ceba9a2009-03-21 03:46:068471// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018472TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068473 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068476
8477 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168478 trans.read_buf_ = new IOBuffer(15);
8479 trans.read_buf_len_ = 15;
8480 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068481
8482 // Setup state in response_
bnc691fda62016-08-12 00:43:168483 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578484 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088485 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578486 response->response_time = base::Time::Now();
8487 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068488
8489 { // Setup state for response_.vary_data
8490 HttpRequestInfo request;
8491 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8492 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278493 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438494 request.extra_headers.SetHeader("Foo", "1");
8495 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508496 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068497 }
8498
8499 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168500 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068501
8502 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168503 EXPECT_FALSE(trans.read_buf_);
8504 EXPECT_EQ(0, trans.read_buf_len_);
8505 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528506 EXPECT_FALSE(response->auth_challenge);
8507 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048508 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088509 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578510 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068511}
8512
[email protected]bacff652009-03-31 17:50:338513// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018514TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338515 HttpRequestInfo request;
8516 request.method = "GET";
bncce36dca22015-04-21 22:11:238517 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108518 request.traffic_annotation =
8519 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338520
danakj1fd259a02016-04-16 03:17:098521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278523
[email protected]bacff652009-03-31 17:50:338524 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238525 MockWrite(
8526 "GET / HTTP/1.1\r\n"
8527 "Host: www.example.org\r\n"
8528 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338529 };
8530
8531 MockRead data_reads[] = {
8532 MockRead("HTTP/1.0 200 OK\r\n"),
8533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8534 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068535 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338536 };
8537
[email protected]5ecc992a42009-11-11 01:41:598538 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398539 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8540 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068541 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8542 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338543
[email protected]bb88e1d32013-05-03 23:11:078544 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8545 session_deps_.socket_factory->AddSocketDataProvider(&data);
8546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8547 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338548
[email protected]49639fa2011-12-20 23:22:418549 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338550
tfarina42834112016-09-22 13:38:208551 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338553
8554 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018555 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338556
bnc691fda62016-08-12 00:43:168557 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338559
8560 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018561 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338562
bnc691fda62016-08-12 00:43:168563 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338564
wezca1070932016-05-26 20:30:528565 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338566 EXPECT_EQ(100, response->headers->GetContentLength());
8567}
8568
8569// Test HTTPS connections to a site with a bad certificate, going through a
8570// proxy
bncd16676a2016-07-20 16:23:018571TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498572 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8573 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338574
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]bacff652009-03-31 17:50:338580
8581 MockWrite proxy_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"),
[email protected]bacff652009-03-31 17:50:338585 };
8586
8587 MockRead proxy_reads[] = {
8588 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068589 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338590 };
8591
8592 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178593 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8594 "Host: www.example.org:443\r\n"
8595 "Proxy-Connection: keep-alive\r\n\r\n"),
8596 MockWrite("GET / HTTP/1.1\r\n"
8597 "Host: www.example.org\r\n"
8598 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338599 };
8600
8601 MockRead data_reads[] = {
8602 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8603 MockRead("HTTP/1.0 200 OK\r\n"),
8604 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8605 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068606 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338607 };
8608
[email protected]31a2bfe2010-02-09 08:03:398609 StaticSocketDataProvider ssl_bad_certificate(
8610 proxy_reads, arraysize(proxy_reads),
8611 proxy_writes, arraysize(proxy_writes));
8612 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8613 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068614 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8615 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338616
[email protected]bb88e1d32013-05-03 23:11:078617 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8618 session_deps_.socket_factory->AddSocketDataProvider(&data);
8619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338621
[email protected]49639fa2011-12-20 23:22:418622 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338623
8624 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078625 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338626
danakj1fd259a02016-04-16 03:17:098627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338629
tfarina42834112016-09-22 13:38:208630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338632
8633 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018634 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338635
bnc691fda62016-08-12 00:43:168636 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338638
8639 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018640 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338641
bnc691fda62016-08-12 00:43:168642 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338643
wezca1070932016-05-26 20:30:528644 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338645 EXPECT_EQ(100, response->headers->GetContentLength());
8646 }
8647}
8648
[email protected]2df19bb2010-08-25 20:13:468649
8650// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018651TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598652 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498653 ProxyResolutionService::CreateFixedFromPacResult(
8654 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518655 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078656 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468657
8658 HttpRequestInfo request;
8659 request.method = "GET";
bncce36dca22015-04-21 22:11:238660 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108661 request.traffic_annotation =
8662 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468663
8664 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178665 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8666 "Host: www.example.org:443\r\n"
8667 "Proxy-Connection: keep-alive\r\n\r\n"),
8668 MockWrite("GET / HTTP/1.1\r\n"
8669 "Host: www.example.org\r\n"
8670 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468671 };
8672
8673 MockRead data_reads[] = {
8674 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8675 MockRead("HTTP/1.1 200 OK\r\n"),
8676 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8677 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068678 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468679 };
8680
8681 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8682 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068683 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8684 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468685
[email protected]bb88e1d32013-05-03 23:11:078686 session_deps_.socket_factory->AddSocketDataProvider(&data);
8687 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8688 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468689
[email protected]49639fa2011-12-20 23:22:418690 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468691
danakj1fd259a02016-04-16 03:17:098692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468694
tfarina42834112016-09-22 13:38:208695 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468697
8698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018699 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168700 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468701
wezca1070932016-05-26 20:30:528702 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468703
tbansal2ecbbc72016-10-06 17:15:478704 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468705 EXPECT_TRUE(response->headers->IsKeepAlive());
8706 EXPECT_EQ(200, response->headers->response_code());
8707 EXPECT_EQ(100, response->headers->GetContentLength());
8708 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208709
8710 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168711 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208712 TestLoadTimingNotReusedWithPac(load_timing_info,
8713 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468714}
8715
[email protected]511f6f52010-12-17 03:58:298716// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018717TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598718 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498719 ProxyResolutionService::CreateFixedFromPacResult(
8720 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518721 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078722 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298723
8724 HttpRequestInfo request;
8725 request.method = "GET";
bncce36dca22015-04-21 22:11:238726 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108727 request.traffic_annotation =
8728 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298729
8730 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178731 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8732 "Host: www.example.org:443\r\n"
8733 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298734 };
8735
8736 MockRead data_reads[] = {
8737 MockRead("HTTP/1.1 302 Redirect\r\n"),
8738 MockRead("Location: http://login.example.com/\r\n"),
8739 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068740 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298741 };
8742
8743 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8744 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068745 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298746
[email protected]bb88e1d32013-05-03 23:11:078747 session_deps_.socket_factory->AddSocketDataProvider(&data);
8748 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298749
[email protected]49639fa2011-12-20 23:22:418750 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298751
danakj1fd259a02016-04-16 03:17:098752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298754
tfarina42834112016-09-22 13:38:208755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298757
8758 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018759 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168760 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298761
wezca1070932016-05-26 20:30:528762 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298763
8764 EXPECT_EQ(302, response->headers->response_code());
8765 std::string url;
8766 EXPECT_TRUE(response->headers->IsRedirect(&url));
8767 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208768
8769 // In the case of redirects from proxies, HttpNetworkTransaction returns
8770 // timing for the proxy connection instead of the connection to the host,
8771 // and no send / receive times.
8772 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8773 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168774 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208775
8776 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198777 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208778
8779 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8780 EXPECT_LE(load_timing_info.proxy_resolve_start,
8781 load_timing_info.proxy_resolve_end);
8782 EXPECT_LE(load_timing_info.proxy_resolve_end,
8783 load_timing_info.connect_timing.connect_start);
8784 ExpectConnectTimingHasTimes(
8785 load_timing_info.connect_timing,
8786 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8787
8788 EXPECT_TRUE(load_timing_info.send_start.is_null());
8789 EXPECT_TRUE(load_timing_info.send_end.is_null());
8790 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298791}
8792
8793// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018794TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498795 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8796 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298797
8798 HttpRequestInfo request;
8799 request.method = "GET";
bncce36dca22015-04-21 22:11:238800 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108801 request.traffic_annotation =
8802 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298803
bncdf80d44fd2016-07-15 20:27:418804 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238805 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418806 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088807 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298808 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418809 CreateMockWrite(conn, 0, SYNCHRONOUS),
8810 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298811 };
8812
8813 static const char* const kExtraHeaders[] = {
8814 "location",
8815 "http://login.example.com/",
8816 };
bnc42331402016-07-25 13:36:158817 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238818 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298819 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418820 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298821 };
8822
rch8e6c6c42015-05-01 14:05:138823 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8824 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068825 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368826 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298827
[email protected]bb88e1d32013-05-03 23:11:078828 session_deps_.socket_factory->AddSocketDataProvider(&data);
8829 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298830
[email protected]49639fa2011-12-20 23:22:418831 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298832
danakj1fd259a02016-04-16 03:17:098833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298835
tfarina42834112016-09-22 13:38:208836 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298838
8839 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018840 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168841 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298842
wezca1070932016-05-26 20:30:528843 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298844
8845 EXPECT_EQ(302, response->headers->response_code());
8846 std::string url;
8847 EXPECT_TRUE(response->headers->IsRedirect(&url));
8848 EXPECT_EQ("http://login.example.com/", url);
8849}
8850
[email protected]4eddbc732012-08-09 05:40:178851// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018852TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498853 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8854 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298855
8856 HttpRequestInfo request;
8857 request.method = "GET";
bncce36dca22015-04-21 22:11:238858 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108859 request.traffic_annotation =
8860 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298861
8862 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178863 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8864 "Host: www.example.org:443\r\n"
8865 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298866 };
8867
8868 MockRead data_reads[] = {
8869 MockRead("HTTP/1.1 404 Not Found\r\n"),
8870 MockRead("Content-Length: 23\r\n\r\n"),
8871 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068872 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298873 };
8874
8875 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8876 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068877 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298878
[email protected]bb88e1d32013-05-03 23:11:078879 session_deps_.socket_factory->AddSocketDataProvider(&data);
8880 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298881
[email protected]49639fa2011-12-20 23:22:418882 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298883
danakj1fd259a02016-04-16 03:17:098884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168885 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298886
tfarina42834112016-09-22 13:38:208887 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298889
8890 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018891 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298892
ttuttle960fcbf2016-04-19 13:26:328893 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298894}
8895
[email protected]4eddbc732012-08-09 05:40:178896// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018897TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498898 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8899 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298900
8901 HttpRequestInfo request;
8902 request.method = "GET";
bncce36dca22015-04-21 22:11:238903 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108904 request.traffic_annotation =
8905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298906
bncdf80d44fd2016-07-15 20:27:418907 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238908 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418909 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088910 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298911 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418912 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298913 };
8914
8915 static const char* const kExtraHeaders[] = {
8916 "location",
8917 "http://login.example.com/",
8918 };
bnc42331402016-07-25 13:36:158919 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238920 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Bence Békyd74f4382018-02-20 18:26:198921 SpdySerializedFrame body(
8922 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298923 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418924 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138925 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298926 };
8927
rch8e6c6c42015-05-01 14:05:138928 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8929 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068930 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368931 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298932
[email protected]bb88e1d32013-05-03 23:11:078933 session_deps_.socket_factory->AddSocketDataProvider(&data);
8934 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298935
[email protected]49639fa2011-12-20 23:22:418936 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298937
danakj1fd259a02016-04-16 03:17:098938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298940
tfarina42834112016-09-22 13:38:208941 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298943
8944 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018945 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298946
ttuttle960fcbf2016-04-19 13:26:328947 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298948}
8949
[email protected]0c5fb722012-02-28 11:50:358950// Test the request-challenge-retry sequence for basic auth, through
8951// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018952TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358953 HttpRequestInfo request;
8954 request.method = "GET";
bncce36dca22015-04-21 22:11:238955 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358956 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298957 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:108958 request.traffic_annotation =
8959 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358960
8961 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598962 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498963 ProxyResolutionService::CreateFixedFromPacResult(
8964 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518965 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078966 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098967 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358968
8969 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418970 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238971 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418972 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088973 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388974 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358975
bnc691fda62016-08-12 00:43:168976 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358977 // be issuing -- the final header line contains the credentials.
8978 const char* const kAuthCredentials[] = {
8979 "proxy-authorization", "Basic Zm9vOmJhcg==",
8980 };
bncdf80d44fd2016-07-15 20:27:418981 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348982 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238983 HostPortPair("www.example.org", 443)));
8984 // fetch https://www.example.org/ via HTTP
8985 const char get[] =
8986 "GET / HTTP/1.1\r\n"
8987 "Host: www.example.org\r\n"
8988 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418989 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198990 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358991
8992 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418993 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8994 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358995 };
8996
8997 // The proxy responds to the connect with a 407, using a persistent
8998 // connection.
thestig9d3bb0c2015-01-24 00:49:518999 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359000 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359001 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9002 };
bnc42331402016-07-25 13:36:159003 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:419004 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359005
bnc42331402016-07-25 13:36:159006 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359007 const char resp[] = "HTTP/1.1 200 OK\r\n"
9008 "Content-Length: 5\r\n\r\n";
9009
bncdf80d44fd2016-07-15 20:27:419010 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199011 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
bncdf80d44fd2016-07-15 20:27:419012 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199013 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359014 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419015 CreateMockRead(conn_auth_resp, 1, ASYNC),
9016 CreateMockRead(conn_resp, 4, ASYNC),
9017 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9018 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139019 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359020 };
9021
rch8e6c6c42015-05-01 14:05:139022 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9023 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079024 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359025 // Negotiate SPDY to the proxy
9026 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369027 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079028 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359029 // Vanilla SSL to the server
9030 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079031 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359032
9033 TestCompletionCallback callback1;
9034
bnc87dcefc2017-05-25 12:47:589035 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199036 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359037
9038 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359040
9041 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019042 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469043 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359044 log.GetEntries(&entries);
9045 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009046 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9047 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359048 ExpectLogContainsSomewhere(
9049 entries, pos,
mikecirone8b85c432016-09-08 19:11:009050 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9051 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359052
9053 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529054 ASSERT_TRUE(response);
9055 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359056 EXPECT_EQ(407, response->headers->response_code());
9057 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529058 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439059 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359060
9061 TestCompletionCallback callback2;
9062
9063 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9064 callback2.callback());
robpercival214763f2016-07-01 23:27:019065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359066
9067 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019068 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359069
9070 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529071 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359072
9073 EXPECT_TRUE(response->headers->IsKeepAlive());
9074 EXPECT_EQ(200, response->headers->response_code());
9075 EXPECT_EQ(5, response->headers->GetContentLength());
9076 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9077
9078 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529079 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359080
[email protected]029c83b62013-01-24 05:28:209081 LoadTimingInfo load_timing_info;
9082 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9083 TestLoadTimingNotReusedWithPac(load_timing_info,
9084 CONNECT_TIMING_HAS_SSL_TIMES);
9085
[email protected]0c5fb722012-02-28 11:50:359086 trans.reset();
9087 session->CloseAllConnections();
9088}
9089
[email protected]7c6f7ba2012-04-03 04:09:299090// Test that an explicitly trusted SPDY proxy can push a resource from an
9091// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019092TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159093 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199094 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159095 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9096 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299097 HttpRequestInfo request;
9098 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109099 request.traffic_annotation =
9100 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299101
[email protected]7c6f7ba2012-04-03 04:09:299102 request.method = "GET";
bncce36dca22015-04-21 22:11:239103 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299104 push_request.method = "GET";
9105 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109106 push_request.traffic_annotation =
9107 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299108
tbansal28e68f82016-02-04 02:56:159109 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599110 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499111 ProxyResolutionService::CreateFixedFromPacResult(
9112 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519113 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079114 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509115
inlinechan894515af2016-12-09 02:40:109116 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509117
danakj1fd259a02016-04-16 03:17:099118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299119
bncdf80d44fd2016-07-15 20:27:419120 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459121 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359122 SpdySerializedFrame stream2_priority(
9123 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299124
9125 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419126 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359127 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299128 };
9129
Bence Béky7bf94362018-01-10 13:19:369130 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9131 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9132
bncdf80d44fd2016-07-15 20:27:419133 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159134 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299135
bncdf80d44fd2016-07-15 20:27:419136 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299137
Bence Békyd74f4382018-02-20 18:26:199138 SpdySerializedFrame stream2_body(
9139 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299140
9141 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369142 CreateMockRead(stream2_syn, 1, ASYNC),
9143 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359144 CreateMockRead(stream1_body, 4, ASYNC),
9145 CreateMockRead(stream2_body, 5, ASYNC),
9146 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299147 };
9148
rch8e6c6c42015-05-01 14:05:139149 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9150 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079151 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299152 // Negotiate SPDY to the proxy
9153 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369154 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079155 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299156
bnc87dcefc2017-05-25 12:47:589157 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199158 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299159 TestCompletionCallback callback;
9160 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299162
9163 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019164 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299165 const HttpResponseInfo* response = trans->GetResponseInfo();
9166
bnc87dcefc2017-05-25 12:47:589167 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199168 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509169 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299171
9172 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019173 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299174 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9175
wezca1070932016-05-26 20:30:529176 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299177 EXPECT_TRUE(response->headers->IsKeepAlive());
9178
9179 EXPECT_EQ(200, response->headers->response_code());
9180 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9181
9182 std::string response_data;
9183 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019184 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299185 EXPECT_EQ("hello!", response_data);
9186
[email protected]029c83b62013-01-24 05:28:209187 LoadTimingInfo load_timing_info;
9188 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9189 TestLoadTimingNotReusedWithPac(load_timing_info,
9190 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9191
[email protected]7c6f7ba2012-04-03 04:09:299192 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529193 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299194 EXPECT_EQ(200, push_response->headers->response_code());
9195
9196 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019197 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299198 EXPECT_EQ("pushed", response_data);
9199
[email protected]029c83b62013-01-24 05:28:209200 LoadTimingInfo push_load_timing_info;
9201 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9202 TestLoadTimingReusedWithPac(push_load_timing_info);
9203 // The transactions should share a socket ID, despite being for different
9204 // origins.
9205 EXPECT_EQ(load_timing_info.socket_log_id,
9206 push_load_timing_info.socket_log_id);
9207
[email protected]7c6f7ba2012-04-03 04:09:299208 trans.reset();
9209 push_trans.reset();
9210 session->CloseAllConnections();
9211}
9212
[email protected]8c843192012-04-05 07:15:009213// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019214TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159215 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199216 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159217 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9218 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009219 HttpRequestInfo request;
9220
9221 request.method = "GET";
bncce36dca22015-04-21 22:11:239222 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109223 request.traffic_annotation =
9224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009225
Ramin Halavatica8d5252018-03-12 05:33:499226 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9227 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519228 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079229 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509230
9231 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109232 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509233
danakj1fd259a02016-04-16 03:17:099234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009235
bncdf80d44fd2016-07-15 20:27:419236 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459237 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009238
bncdf80d44fd2016-07-15 20:27:419239 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089240 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009241
9242 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419243 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009244 };
9245
bncdf80d44fd2016-07-15 20:27:419246 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159247 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009248
bncdf80d44fd2016-07-15 20:27:419249 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009250
bncdf80d44fd2016-07-15 20:27:419251 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559252 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009253
9254 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419255 CreateMockRead(stream1_reply, 1, ASYNC),
9256 CreateMockRead(stream2_syn, 2, ASYNC),
9257 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599258 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009259 };
9260
rch8e6c6c42015-05-01 14:05:139261 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9262 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079263 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009264 // Negotiate SPDY to the proxy
9265 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369266 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079267 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009268
bnc87dcefc2017-05-25 12:47:589269 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199270 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009271 TestCompletionCallback callback;
9272 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009274
9275 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019276 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009277 const HttpResponseInfo* response = trans->GetResponseInfo();
9278
wezca1070932016-05-26 20:30:529279 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009280 EXPECT_TRUE(response->headers->IsKeepAlive());
9281
9282 EXPECT_EQ(200, response->headers->response_code());
9283 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9284
9285 std::string response_data;
9286 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019287 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009288 EXPECT_EQ("hello!", response_data);
9289
9290 trans.reset();
9291 session->CloseAllConnections();
9292}
9293
tbansal8ef1d3e2016-02-03 04:05:429294// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9295// resources.
bncd16676a2016-07-20 16:23:019296TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159297 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199298 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159299 proxy_delegate->set_trusted_spdy_proxy(
9300 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9301
tbansal8ef1d3e2016-02-03 04:05:429302 HttpRequestInfo request;
9303
9304 request.method = "GET";
9305 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109306 request.traffic_annotation =
9307 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429308
9309 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499310 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9311 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429312 BoundTestNetLog log;
9313 session_deps_.net_log = log.bound().net_log();
9314
9315 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109316 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429317
danakj1fd259a02016-04-16 03:17:099318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429319
bncdf80d44fd2016-07-15 20:27:419320 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459321 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359322 SpdySerializedFrame stream2_priority(
9323 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429324
9325 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419326 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359327 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429328 };
9329
bncdf80d44fd2016-07-15 20:27:419330 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159331 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429332
bncdf80d44fd2016-07-15 20:27:419333 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339334 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499335
bncdf80d44fd2016-07-15 20:27:419336 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429337
bncdf80d44fd2016-07-15 20:27:419338 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159339 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429340
bncdf80d44fd2016-07-15 20:27:419341 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429342
9343 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419344 CreateMockRead(stream1_reply, 1, ASYNC),
9345 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359346 CreateMockRead(stream1_body, 4, ASYNC),
9347 CreateMockRead(stream2_body, 5, ASYNC),
9348 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429349 };
9350
9351 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9352 arraysize(spdy_writes));
9353 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9354 // Negotiate SPDY to the proxy
9355 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369356 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429357 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9358
bnc87dcefc2017-05-25 12:47:589359 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199360 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429361 TestCompletionCallback callback;
9362 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429364
9365 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019366 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429367 const HttpResponseInfo* response = trans->GetResponseInfo();
9368
wezca1070932016-05-26 20:30:529369 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429370 EXPECT_TRUE(response->headers->IsKeepAlive());
9371
9372 EXPECT_EQ(200, response->headers->response_code());
9373 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9374
9375 std::string response_data;
9376 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019377 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429378 EXPECT_EQ("hello!", response_data);
9379
9380 trans.reset();
9381 session->CloseAllConnections();
9382}
9383
[email protected]2df19bb2010-08-25 20:13:469384// Test HTTPS connections to a site with a bad certificate, going through an
9385// HTTPS proxy
bncd16676a2016-07-20 16:23:019386TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499387 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9388 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469389
9390 HttpRequestInfo request;
9391 request.method = "GET";
bncce36dca22015-04-21 22:11:239392 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109393 request.traffic_annotation =
9394 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469395
9396 // Attempt to fetch the URL from a server with a bad cert
9397 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179398 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9399 "Host: www.example.org:443\r\n"
9400 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469401 };
9402
9403 MockRead bad_cert_reads[] = {
9404 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069405 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469406 };
9407
9408 // Attempt to fetch the URL with a good cert
9409 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179410 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9411 "Host: www.example.org:443\r\n"
9412 "Proxy-Connection: keep-alive\r\n\r\n"),
9413 MockWrite("GET / HTTP/1.1\r\n"
9414 "Host: www.example.org\r\n"
9415 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469416 };
9417
9418 MockRead good_cert_reads[] = {
9419 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9420 MockRead("HTTP/1.0 200 OK\r\n"),
9421 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9422 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069423 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469424 };
9425
9426 StaticSocketDataProvider ssl_bad_certificate(
9427 bad_cert_reads, arraysize(bad_cert_reads),
9428 bad_cert_writes, arraysize(bad_cert_writes));
9429 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9430 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069431 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9432 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469433
9434 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079435 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9436 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469438
9439 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9441 session_deps_.socket_factory->AddSocketDataProvider(&data);
9442 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469443
[email protected]49639fa2011-12-20 23:22:419444 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469445
danakj1fd259a02016-04-16 03:17:099446 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469448
tfarina42834112016-09-22 13:38:209449 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469451
9452 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019453 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469454
bnc691fda62016-08-12 00:43:169455 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469457
9458 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019459 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469460
bnc691fda62016-08-12 00:43:169461 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469462
wezca1070932016-05-26 20:30:529463 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469464 EXPECT_EQ(100, response->headers->GetContentLength());
9465}
9466
bncd16676a2016-07-20 16:23:019467TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429468 HttpRequestInfo request;
9469 request.method = "GET";
bncce36dca22015-04-21 22:11:239470 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439471 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9472 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109473 request.traffic_annotation =
9474 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429475
danakj1fd259a02016-04-16 03:17:099476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279478
[email protected]1c773ea12009-04-28 19:58:429479 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239480 MockWrite(
9481 "GET / HTTP/1.1\r\n"
9482 "Host: www.example.org\r\n"
9483 "Connection: keep-alive\r\n"
9484 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429485 };
9486
9487 // Lastly, the server responds with the actual content.
9488 MockRead data_reads[] = {
9489 MockRead("HTTP/1.0 200 OK\r\n"),
9490 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9491 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069492 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429493 };
9494
[email protected]31a2bfe2010-02-09 08:03:399495 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9496 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079497 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429498
[email protected]49639fa2011-12-20 23:22:419499 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429500
tfarina42834112016-09-22 13:38:209501 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429503
9504 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019505 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429506}
9507
bncd16676a2016-07-20 16:23:019508TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299509 HttpRequestInfo request;
9510 request.method = "GET";
bncce36dca22015-04-21 22:11:239511 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299512 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9513 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109514 request.traffic_annotation =
9515 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299516
Ramin Halavatica8d5252018-03-12 05:33:499517 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9518 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099519 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169520 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279521
[email protected]da81f132010-08-18 23:39:299522 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179523 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9524 "Host: www.example.org:443\r\n"
9525 "Proxy-Connection: keep-alive\r\n"
9526 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299527 };
9528 MockRead data_reads[] = {
9529 // Return an error, so the transaction stops here (this test isn't
9530 // interested in the rest).
9531 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9532 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9533 MockRead("Proxy-Connection: close\r\n\r\n"),
9534 };
9535
9536 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9537 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079538 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299539
[email protected]49639fa2011-12-20 23:22:419540 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299541
tfarina42834112016-09-22 13:38:209542 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299544
9545 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019546 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299547}
9548
bncd16676a2016-07-20 16:23:019549TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429550 HttpRequestInfo request;
9551 request.method = "GET";
bncce36dca22015-04-21 22:11:239552 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169553 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9554 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:109555 request.traffic_annotation =
9556 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429557
danakj1fd259a02016-04-16 03:17:099558 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279560
[email protected]1c773ea12009-04-28 19:58:429561 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239562 MockWrite(
9563 "GET / HTTP/1.1\r\n"
9564 "Host: www.example.org\r\n"
9565 "Connection: keep-alive\r\n"
9566 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429567 };
9568
9569 // Lastly, the server responds with the actual content.
9570 MockRead data_reads[] = {
9571 MockRead("HTTP/1.0 200 OK\r\n"),
9572 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9573 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069574 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429575 };
9576
[email protected]31a2bfe2010-02-09 08:03:399577 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9578 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079579 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429580
[email protected]49639fa2011-12-20 23:22:419581 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429582
tfarina42834112016-09-22 13:38:209583 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429585
9586 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019587 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429588}
9589
bncd16676a2016-07-20 16:23:019590TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429591 HttpRequestInfo request;
9592 request.method = "POST";
bncce36dca22015-04-21 22:11:239593 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109594 request.traffic_annotation =
9595 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429596
danakj1fd259a02016-04-16 03:17:099597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279599
[email protected]1c773ea12009-04-28 19:58:429600 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239601 MockWrite(
9602 "POST / HTTP/1.1\r\n"
9603 "Host: www.example.org\r\n"
9604 "Connection: keep-alive\r\n"
9605 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429606 };
9607
9608 // Lastly, the server responds with the actual content.
9609 MockRead data_reads[] = {
9610 MockRead("HTTP/1.0 200 OK\r\n"),
9611 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9612 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069613 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429614 };
9615
[email protected]31a2bfe2010-02-09 08:03:399616 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9617 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429619
[email protected]49639fa2011-12-20 23:22:419620 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429621
tfarina42834112016-09-22 13:38:209622 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429624
9625 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019626 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429627}
9628
bncd16676a2016-07-20 16:23:019629TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429630 HttpRequestInfo request;
9631 request.method = "PUT";
bncce36dca22015-04-21 22:11:239632 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109633 request.traffic_annotation =
9634 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429635
danakj1fd259a02016-04-16 03:17:099636 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279638
[email protected]1c773ea12009-04-28 19:58:429639 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239640 MockWrite(
9641 "PUT / HTTP/1.1\r\n"
9642 "Host: www.example.org\r\n"
9643 "Connection: keep-alive\r\n"
9644 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429645 };
9646
9647 // Lastly, the server responds with the actual content.
9648 MockRead data_reads[] = {
9649 MockRead("HTTP/1.0 200 OK\r\n"),
9650 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9651 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069652 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429653 };
9654
[email protected]31a2bfe2010-02-09 08:03:399655 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9656 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079657 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429658
[email protected]49639fa2011-12-20 23:22:419659 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429660
tfarina42834112016-09-22 13:38:209661 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429663
9664 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019665 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429666}
9667
bncd16676a2016-07-20 16:23:019668TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429669 HttpRequestInfo request;
9670 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239671 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109672 request.traffic_annotation =
9673 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429674
danakj1fd259a02016-04-16 03:17:099675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279677
[email protected]1c773ea12009-04-28 19:58:429678 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139679 MockWrite("HEAD / HTTP/1.1\r\n"
9680 "Host: www.example.org\r\n"
9681 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429682 };
9683
9684 // Lastly, the server responds with the actual content.
9685 MockRead data_reads[] = {
9686 MockRead("HTTP/1.0 200 OK\r\n"),
9687 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9688 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069689 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429690 };
9691
[email protected]31a2bfe2010-02-09 08:03:399692 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9693 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079694 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429695
[email protected]49639fa2011-12-20 23:22:419696 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429697
tfarina42834112016-09-22 13:38:209698 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429700
9701 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019702 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429703}
9704
bncd16676a2016-07-20 16:23:019705TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429706 HttpRequestInfo request;
9707 request.method = "GET";
bncce36dca22015-04-21 22:11:239708 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429709 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109710 request.traffic_annotation =
9711 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429712
danakj1fd259a02016-04-16 03:17:099713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279715
[email protected]1c773ea12009-04-28 19:58:429716 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239717 MockWrite(
9718 "GET / HTTP/1.1\r\n"
9719 "Host: www.example.org\r\n"
9720 "Connection: keep-alive\r\n"
9721 "Pragma: no-cache\r\n"
9722 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429723 };
9724
9725 // Lastly, the server responds with the actual content.
9726 MockRead data_reads[] = {
9727 MockRead("HTTP/1.0 200 OK\r\n"),
9728 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9729 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069730 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429731 };
9732
[email protected]31a2bfe2010-02-09 08:03:399733 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9734 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079735 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429736
[email protected]49639fa2011-12-20 23:22:419737 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429738
tfarina42834112016-09-22 13:38:209739 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429741
9742 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019743 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429744}
9745
bncd16676a2016-07-20 16:23:019746TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429747 HttpRequestInfo request;
9748 request.method = "GET";
bncce36dca22015-04-21 22:11:239749 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429750 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109751 request.traffic_annotation =
9752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429753
danakj1fd259a02016-04-16 03:17:099754 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279756
[email protected]1c773ea12009-04-28 19:58:429757 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239758 MockWrite(
9759 "GET / HTTP/1.1\r\n"
9760 "Host: www.example.org\r\n"
9761 "Connection: keep-alive\r\n"
9762 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429763 };
9764
9765 // Lastly, the server responds with the actual content.
9766 MockRead data_reads[] = {
9767 MockRead("HTTP/1.0 200 OK\r\n"),
9768 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9769 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069770 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429771 };
9772
[email protected]31a2bfe2010-02-09 08:03:399773 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9774 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079775 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429776
[email protected]49639fa2011-12-20 23:22:419777 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429778
tfarina42834112016-09-22 13:38:209779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429781
9782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019783 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429784}
9785
bncd16676a2016-07-20 16:23:019786TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429787 HttpRequestInfo request;
9788 request.method = "GET";
bncce36dca22015-04-21 22:11:239789 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439790 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:109791 request.traffic_annotation =
9792 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429793
danakj1fd259a02016-04-16 03:17:099794 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169795 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279796
[email protected]1c773ea12009-04-28 19:58:429797 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239798 MockWrite(
9799 "GET / HTTP/1.1\r\n"
9800 "Host: www.example.org\r\n"
9801 "Connection: keep-alive\r\n"
9802 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429803 };
9804
9805 // Lastly, the server responds with the actual content.
9806 MockRead data_reads[] = {
9807 MockRead("HTTP/1.0 200 OK\r\n"),
9808 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9809 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069810 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429811 };
9812
[email protected]31a2bfe2010-02-09 08:03:399813 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9814 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079815 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429816
[email protected]49639fa2011-12-20 23:22:419817 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429818
tfarina42834112016-09-22 13:38:209819 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429821
9822 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019823 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429824}
9825
bncd16676a2016-07-20 16:23:019826TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479827 HttpRequestInfo request;
9828 request.method = "GET";
bncce36dca22015-04-21 22:11:239829 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439830 request.extra_headers.SetHeader("referer", "www.foo.com");
9831 request.extra_headers.SetHeader("hEllo", "Kitty");
9832 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:109833 request.traffic_annotation =
9834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479835
danakj1fd259a02016-04-16 03:17:099836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279838
[email protected]270c6412010-03-29 22:02:479839 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239840 MockWrite(
9841 "GET / HTTP/1.1\r\n"
9842 "Host: www.example.org\r\n"
9843 "Connection: keep-alive\r\n"
9844 "referer: www.foo.com\r\n"
9845 "hEllo: Kitty\r\n"
9846 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479847 };
9848
9849 // Lastly, the server responds with the actual content.
9850 MockRead data_reads[] = {
9851 MockRead("HTTP/1.0 200 OK\r\n"),
9852 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9853 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069854 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479855 };
9856
9857 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9858 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079859 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479860
[email protected]49639fa2011-12-20 23:22:419861 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479862
tfarina42834112016-09-22 13:38:209863 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479865
9866 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019867 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479868}
9869
bncd16676a2016-07-20 16:23:019870TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279871 HttpRequestInfo request;
9872 request.method = "GET";
bncce36dca22015-04-21 22:11:239873 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109874 request.traffic_annotation =
9875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279876
Lily Houghton8c2f97d2018-01-22 05:06:599877 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499878 ProxyResolutionService::CreateFixedFromPacResult(
9879 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519880 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079881 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029882
danakj1fd259a02016-04-16 03:17:099883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169884 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029885
[email protected]3cd17242009-06-23 02:59:029886 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9887 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9888
9889 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239890 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9891 MockWrite(
9892 "GET / HTTP/1.1\r\n"
9893 "Host: www.example.org\r\n"
9894 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029895
9896 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069897 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029898 MockRead("HTTP/1.0 200 OK\r\n"),
9899 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9900 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069901 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029902 };
9903
[email protected]31a2bfe2010-02-09 08:03:399904 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9905 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079906 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029907
[email protected]49639fa2011-12-20 23:22:419908 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029909
tfarina42834112016-09-22 13:38:209910 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029912
9913 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019914 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029915
bnc691fda62016-08-12 00:43:169916 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529917 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029918
tbansal2ecbbc72016-10-06 17:15:479919 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209920 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169921 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209922 TestLoadTimingNotReusedWithPac(load_timing_info,
9923 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9924
[email protected]3cd17242009-06-23 02:59:029925 std::string response_text;
bnc691fda62016-08-12 00:43:169926 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019927 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029928 EXPECT_EQ("Payload", response_text);
9929}
9930
bncd16676a2016-07-20 16:23:019931TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279932 HttpRequestInfo request;
9933 request.method = "GET";
bncce36dca22015-04-21 22:11:239934 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109935 request.traffic_annotation =
9936 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279937
Lily Houghton8c2f97d2018-01-22 05:06:599938 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499939 ProxyResolutionService::CreateFixedFromPacResult(
9940 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519941 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079942 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029943
danakj1fd259a02016-04-16 03:17:099944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029946
[email protected]3cd17242009-06-23 02:59:029947 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9948 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9949
9950 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239951 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9952 arraysize(write_buffer)),
9953 MockWrite(
9954 "GET / HTTP/1.1\r\n"
9955 "Host: www.example.org\r\n"
9956 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029957
9958 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019959 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9960 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359961 MockRead("HTTP/1.0 200 OK\r\n"),
9962 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9963 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069964 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359965 };
9966
[email protected]31a2bfe2010-02-09 08:03:399967 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9968 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079969 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359970
[email protected]8ddf8322012-02-23 18:08:069971 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079972 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359973
[email protected]49639fa2011-12-20 23:22:419974 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359975
tfarina42834112016-09-22 13:38:209976 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359978
9979 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019980 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359981
[email protected]029c83b62013-01-24 05:28:209982 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169983 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209984 TestLoadTimingNotReusedWithPac(load_timing_info,
9985 CONNECT_TIMING_HAS_SSL_TIMES);
9986
bnc691fda62016-08-12 00:43:169987 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529988 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479989 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359990
9991 std::string response_text;
bnc691fda62016-08-12 00:43:169992 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019993 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359994 EXPECT_EQ("Payload", response_text);
9995}
9996
bncd16676a2016-07-20 16:23:019997TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209998 HttpRequestInfo request;
9999 request.method = "GET";
bncce36dca22015-04-21 22:11:2310000 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010001 request.traffic_annotation =
10002 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010003
Ramin Halavatica8d5252018-03-12 05:33:4910004 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10005 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110006 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710007 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010008
danakj1fd259a02016-04-16 03:17:0910009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010011
10012 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10013 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10014
10015 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310016 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
10017 MockWrite(
10018 "GET / HTTP/1.1\r\n"
10019 "Host: www.example.org\r\n"
10020 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010021
10022 MockRead data_reads[] = {
10023 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
10024 MockRead("HTTP/1.0 200 OK\r\n"),
10025 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10026 MockRead("Payload"),
10027 MockRead(SYNCHRONOUS, OK)
10028 };
10029
10030 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10031 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710032 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010033
10034 TestCompletionCallback callback;
10035
tfarina42834112016-09-22 13:38:2010036 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010038
10039 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110040 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010041
bnc691fda62016-08-12 00:43:1610042 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210043 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010044
10045 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610046 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010047 TestLoadTimingNotReused(load_timing_info,
10048 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10049
10050 std::string response_text;
bnc691fda62016-08-12 00:43:1610051 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110052 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010053 EXPECT_EQ("Payload", response_text);
10054}
10055
bncd16676a2016-07-20 16:23:0110056TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710057 HttpRequestInfo request;
10058 request.method = "GET";
bncce36dca22015-04-21 22:11:2310059 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010060 request.traffic_annotation =
10061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710062
Lily Houghton8c2f97d2018-01-22 05:06:5910063 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910064 ProxyResolutionService::CreateFixedFromPacResult(
10065 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110066 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710067 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510068
danakj1fd259a02016-04-16 03:17:0910069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510071
[email protected]e0c27be2009-07-15 13:09:3510072 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10073 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710074 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310075 0x05, // Version
10076 0x01, // Command (CONNECT)
10077 0x00, // Reserved.
10078 0x03, // Address type (DOMAINNAME).
10079 0x0F, // Length of domain (15)
10080 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10081 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710082 };
[email protected]e0c27be2009-07-15 13:09:3510083 const char kSOCKS5OkResponse[] =
10084 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10085
10086 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310087 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10088 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10089 MockWrite(
10090 "GET / HTTP/1.1\r\n"
10091 "Host: www.example.org\r\n"
10092 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510093
10094 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110095 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10096 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510097 MockRead("HTTP/1.0 200 OK\r\n"),
10098 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10099 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610100 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510101 };
10102
[email protected]31a2bfe2010-02-09 08:03:3910103 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10104 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710105 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510106
[email protected]49639fa2011-12-20 23:22:4110107 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510108
tfarina42834112016-09-22 13:38:2010109 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510111
10112 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110113 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510114
bnc691fda62016-08-12 00:43:1610115 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210116 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710117 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510118
[email protected]029c83b62013-01-24 05:28:2010119 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610120 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010121 TestLoadTimingNotReusedWithPac(load_timing_info,
10122 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10123
[email protected]e0c27be2009-07-15 13:09:3510124 std::string response_text;
bnc691fda62016-08-12 00:43:1610125 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110126 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510127 EXPECT_EQ("Payload", response_text);
10128}
10129
bncd16676a2016-07-20 16:23:0110130TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710131 HttpRequestInfo request;
10132 request.method = "GET";
bncce36dca22015-04-21 22:11:2310133 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010134 request.traffic_annotation =
10135 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710136
Lily Houghton8c2f97d2018-01-22 05:06:5910137 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910138 ProxyResolutionService::CreateFixedFromPacResult(
10139 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110140 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710141 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510142
danakj1fd259a02016-04-16 03:17:0910143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510145
[email protected]e0c27be2009-07-15 13:09:3510146 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10147 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710148 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310149 0x05, // Version
10150 0x01, // Command (CONNECT)
10151 0x00, // Reserved.
10152 0x03, // Address type (DOMAINNAME).
10153 0x0F, // Length of domain (15)
10154 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10155 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710156 };
10157
[email protected]e0c27be2009-07-15 13:09:3510158 const char kSOCKS5OkResponse[] =
10159 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10160
10161 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310162 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10163 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10164 arraysize(kSOCKS5OkRequest)),
10165 MockWrite(
10166 "GET / HTTP/1.1\r\n"
10167 "Host: www.example.org\r\n"
10168 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510169
10170 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110171 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10172 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210173 MockRead("HTTP/1.0 200 OK\r\n"),
10174 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10175 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610176 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210177 };
10178
[email protected]31a2bfe2010-02-09 08:03:3910179 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10180 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710181 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210182
[email protected]8ddf8322012-02-23 18:08:0610183 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210185
[email protected]49639fa2011-12-20 23:22:4110186 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210187
tfarina42834112016-09-22 13:38:2010188 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210190
10191 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110192 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210193
bnc691fda62016-08-12 00:43:1610194 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210195 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710196 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210197
[email protected]029c83b62013-01-24 05:28:2010198 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610199 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010200 TestLoadTimingNotReusedWithPac(load_timing_info,
10201 CONNECT_TIMING_HAS_SSL_TIMES);
10202
[email protected]3cd17242009-06-23 02:59:0210203 std::string response_text;
bnc691fda62016-08-12 00:43:1610204 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110205 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210206 EXPECT_EQ("Payload", response_text);
10207}
10208
[email protected]448d4ca52012-03-04 04:12:2310209namespace {
10210
[email protected]04e5be32009-06-26 20:00:3110211// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610212
10213struct GroupNameTest {
10214 std::string proxy_server;
10215 std::string url;
10216 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810217 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610218};
10219
danakj1fd259a02016-04-16 03:17:0910220std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710221 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910222 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610223
bnc525e175a2016-06-20 12:36:4010224 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310225 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110226 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210227 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110228 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210229 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610230 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610231
10232 return session;
10233}
10234
mmenkee65e7af2015-10-13 17:16:4210235int GroupNameTransactionHelper(const std::string& url,
10236 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610237 HttpRequestInfo request;
10238 request.method = "GET";
10239 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1010240 request.traffic_annotation =
10241 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610242
bnc691fda62016-08-12 00:43:1610243 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710244
[email protected]49639fa2011-12-20 23:22:4110245 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610246
10247 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010248 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610249}
10250
[email protected]448d4ca52012-03-04 04:12:2310251} // namespace
10252
bncd16676a2016-07-20 16:23:0110253TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610254 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310255 {
10256 "", // unused
10257 "http://www.example.org/direct",
10258 "www.example.org:80",
10259 false,
10260 },
10261 {
10262 "", // unused
10263 "http://[2001:1418:13:1::25]/direct",
10264 "[2001:1418:13:1::25]:80",
10265 false,
10266 },
[email protected]04e5be32009-06-26 20:00:3110267
bncce36dca22015-04-21 22:11:2310268 // SSL Tests
10269 {
10270 "", // unused
10271 "https://www.example.org/direct_ssl",
10272 "ssl/www.example.org:443",
10273 true,
10274 },
10275 {
10276 "", // unused
10277 "https://[2001:1418:13:1::25]/direct",
10278 "ssl/[2001:1418:13:1::25]:443",
10279 true,
10280 },
10281 {
10282 "", // unused
bncaa60ff402016-06-22 19:12:4210283 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310284 "ssl/host.with.alternate:443",
10285 true,
10286 },
[email protected]2d731a32010-04-29 01:04:0610287 };
[email protected]2ff8b312010-04-26 22:20:5410288
viettrungluue4a8b882014-10-16 06:17:3810289 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910290 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910291 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10292 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910293 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010294 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610295
mmenkee65e7af2015-10-13 17:16:4210296 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810297 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810298 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310299 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810300 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910301 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210302 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10303 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810304 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610305
10306 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210307 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910308 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810309 EXPECT_EQ(tests[i].expected_group_name,
10310 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910311 } else {
[email protected]e60e47a2010-07-14 03:37:1810312 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810313 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910314 }
10315 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10316 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10317 // When SSL proxy is not in use, socket must be requested from
10318 // |transport_conn_pool|.
10319 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610320 }
[email protected]2d731a32010-04-29 01:04:0610321}
10322
bncd16676a2016-07-20 16:23:0110323TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610324 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310325 {
Matt Menked1eb6d42018-01-17 04:54:0610326 "http_proxy", "http://www.example.org/http_proxy_normal",
10327 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310328 },
[email protected]2d731a32010-04-29 01:04:0610329
bncce36dca22015-04-21 22:11:2310330 // SSL Tests
10331 {
Matt Menked1eb6d42018-01-17 04:54:0610332 "http_proxy", "https://www.example.org/http_connect_ssl",
10333 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310334 },
[email protected]af3490e2010-10-16 21:02:2910335
bncce36dca22015-04-21 22:11:2310336 {
Matt Menked1eb6d42018-01-17 04:54:0610337 "http_proxy", "https://host.with.alternate/direct",
10338 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310339 },
[email protected]45499252013-01-23 17:12:5610340
bncce36dca22015-04-21 22:11:2310341 {
Matt Menked1eb6d42018-01-17 04:54:0610342 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10343 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310344 },
[email protected]2d731a32010-04-29 01:04:0610345 };
10346
viettrungluue4a8b882014-10-16 06:17:3810347 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910348 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910349 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10350 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910351 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010352 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610353
mmenkee65e7af2015-10-13 17:16:4210354 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610355
[email protected]e60e47a2010-07-14 03:37:1810356 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310357 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410358 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310359 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410360 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910361 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910362 mock_pool_manager->SetSocketPoolForHTTPProxy(
10363 proxy_host, base::WrapUnique(http_proxy_pool));
10364 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10365 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810366 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610367
10368 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210369 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810370 if (tests[i].ssl)
10371 EXPECT_EQ(tests[i].expected_group_name,
10372 ssl_conn_pool->last_group_name_received());
10373 else
10374 EXPECT_EQ(tests[i].expected_group_name,
10375 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610376 }
[email protected]2d731a32010-04-29 01:04:0610377}
10378
bncd16676a2016-07-20 16:23:0110379TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610380 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310381 {
10382 "socks4://socks_proxy:1080",
10383 "http://www.example.org/socks4_direct",
10384 "socks4/www.example.org:80",
10385 false,
10386 },
10387 {
10388 "socks5://socks_proxy:1080",
10389 "http://www.example.org/socks5_direct",
10390 "socks5/www.example.org:80",
10391 false,
10392 },
[email protected]2d731a32010-04-29 01:04:0610393
bncce36dca22015-04-21 22:11:2310394 // SSL Tests
10395 {
10396 "socks4://socks_proxy:1080",
10397 "https://www.example.org/socks4_ssl",
10398 "socks4/ssl/www.example.org:443",
10399 true,
10400 },
10401 {
10402 "socks5://socks_proxy:1080",
10403 "https://www.example.org/socks5_ssl",
10404 "socks5/ssl/www.example.org:443",
10405 true,
10406 },
[email protected]af3490e2010-10-16 21:02:2910407
bncce36dca22015-04-21 22:11:2310408 {
10409 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210410 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310411 "socks4/ssl/host.with.alternate:443",
10412 true,
10413 },
[email protected]04e5be32009-06-26 20:00:3110414 };
10415
viettrungluue4a8b882014-10-16 06:17:3810416 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910417 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910418 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10419 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910420 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010421 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210422
mmenkee65e7af2015-10-13 17:16:4210423 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110424
[email protected]e60e47a2010-07-14 03:37:1810425 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310426 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410427 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310428 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410429 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910430 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910431 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10432 proxy_host, base::WrapUnique(socks_conn_pool));
10433 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10434 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810435 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110436
bnc691fda62016-08-12 00:43:1610437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110438
[email protected]2d731a32010-04-29 01:04:0610439 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210440 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810441 if (tests[i].ssl)
10442 EXPECT_EQ(tests[i].expected_group_name,
10443 ssl_conn_pool->last_group_name_received());
10444 else
10445 EXPECT_EQ(tests[i].expected_group_name,
10446 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110447 }
10448}
10449
bncd16676a2016-07-20 16:23:0110450TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710451 HttpRequestInfo request;
10452 request.method = "GET";
bncce36dca22015-04-21 22:11:2310453 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010454 request.traffic_annotation =
10455 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710456
Ramin Halavatica8d5252018-03-12 05:33:4910457 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10458 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210459
[email protected]69719062010-01-05 20:09:2110460 // This simulates failure resolving all hostnames; that means we will fail
10461 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710462 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210463
danakj1fd259a02016-04-16 03:17:0910464 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510466
[email protected]49639fa2011-12-20 23:22:4110467 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510468
tfarina42834112016-09-22 13:38:2010469 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510471
[email protected]9172a982009-06-06 00:30:2510472 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110473 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510474}
10475
Miriam Gershenson2a01b162018-03-22 22:54:4710476// LOAD_BYPASS_CACHE should trigger the host cache bypass.
10477TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2710478 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010479 HttpRequestInfo request_info;
10480 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4710481 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1010482 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010483 request_info.traffic_annotation =
10484 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710485
[email protected]a2c2fb92009-07-18 07:31:0410486 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910487 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210488
danakj1fd259a02016-04-16 03:17:0910489 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610490 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810491
bncce36dca22015-04-21 22:11:2310492 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810493 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910494 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010495 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710496 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310497 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010498 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010499 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710501 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110502 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810503
10504 // Verify that it was added to host cache, by doing a subsequent async lookup
10505 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010506 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710507 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310508 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010509 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010510 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110511 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810512
bncce36dca22015-04-21 22:11:2310513 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810514 // we can tell if the next lookup hit the cache, or the "network".
10515 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310516 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810517
10518 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10519 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610520 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910521 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710522 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810523
[email protected]3b9cca42009-06-16 01:08:2810524 // Run the request.
tfarina42834112016-09-22 13:38:2010525 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110526 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110527 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810528
10529 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310530 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110531 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810532}
10533
[email protected]0877e3d2009-10-17 22:29:5710534// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110535TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710536 HttpRequestInfo request;
10537 request.method = "GET";
10538 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010539 request.traffic_annotation =
10540 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710541
10542 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610543 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710544 };
[email protected]31a2bfe2010-02-09 08:03:3910545 StaticSocketDataProvider data(NULL, 0,
10546 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710547 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710549
[email protected]49639fa2011-12-20 23:22:4110550 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710551
bnc691fda62016-08-12 00:43:1610552 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710553
tfarina42834112016-09-22 13:38:2010554 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710556
10557 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110558 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910559
10560 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610561 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910562 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710563}
10564
zmo9528c9f42015-08-04 22:12:0810565// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110566TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710567 HttpRequestInfo request;
10568 request.method = "GET";
10569 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010570 request.traffic_annotation =
10571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710572
10573 MockRead data_reads[] = {
10574 MockRead("HTTP/1."),
[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 data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710579 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710581
[email protected]49639fa2011-12-20 23:22:4110582 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710583
bnc691fda62016-08-12 00:43:1610584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710585
tfarina42834112016-09-22 13:38:2010586 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110587 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710588
10589 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110590 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810591
bnc691fda62016-08-12 00:43:1610592 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210593 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810594
wezca1070932016-05-26 20:30:5210595 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810596 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10597
10598 std::string response_data;
bnc691fda62016-08-12 00:43:1610599 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110600 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810601 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910602
10603 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610604 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910605 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710606}
10607
10608// Make sure that a dropped connection while draining the body for auth
10609// restart does the right thing.
bncd16676a2016-07-20 16:23:0110610TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710611 HttpRequestInfo request;
10612 request.method = "GET";
bncce36dca22015-04-21 22:11:2310613 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010614 request.traffic_annotation =
10615 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710616
10617 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310618 MockWrite(
10619 "GET / HTTP/1.1\r\n"
10620 "Host: www.example.org\r\n"
10621 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710622 };
10623
10624 MockRead data_reads1[] = {
10625 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10626 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10628 MockRead("Content-Length: 14\r\n\r\n"),
10629 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610630 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710631 };
10632
[email protected]31a2bfe2010-02-09 08:03:3910633 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10634 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710635 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710636
bnc691fda62016-08-12 00:43:1610637 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710638 // be issuing -- the final header line contains the credentials.
10639 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310640 MockWrite(
10641 "GET / HTTP/1.1\r\n"
10642 "Host: www.example.org\r\n"
10643 "Connection: keep-alive\r\n"
10644 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710645 };
10646
10647 // Lastly, the server responds with the actual content.
10648 MockRead data_reads2[] = {
10649 MockRead("HTTP/1.1 200 OK\r\n"),
10650 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10651 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610652 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710653 };
10654
[email protected]31a2bfe2010-02-09 08:03:3910655 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10656 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710657 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710659
[email protected]49639fa2011-12-20 23:22:4110660 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710661
bnc691fda62016-08-12 00:43:1610662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010663
tfarina42834112016-09-22 13:38:2010664 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710666
10667 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110668 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710669
bnc691fda62016-08-12 00:43:1610670 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210671 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410672 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710673
[email protected]49639fa2011-12-20 23:22:4110674 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710675
bnc691fda62016-08-12 00:43:1610676 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710678
10679 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110680 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710681
bnc691fda62016-08-12 00:43:1610682 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210683 ASSERT_TRUE(response);
10684 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710685 EXPECT_EQ(100, response->headers->GetContentLength());
10686}
10687
10688// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110689TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910690 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10691 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710692
10693 HttpRequestInfo request;
10694 request.method = "GET";
bncce36dca22015-04-21 22:11:2310695 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010696 request.traffic_annotation =
10697 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710698
10699 MockRead proxy_reads[] = {
10700 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610701 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710702 };
10703
[email protected]31a2bfe2010-02-09 08:03:3910704 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610705 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710706
[email protected]bb88e1d32013-05-03 23:11:0710707 session_deps_.socket_factory->AddSocketDataProvider(&data);
10708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710709
[email protected]49639fa2011-12-20 23:22:4110710 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710711
[email protected]bb88e1d32013-05-03 23:11:0710712 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710713
danakj1fd259a02016-04-16 03:17:0910714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710716
tfarina42834112016-09-22 13:38:2010717 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710719
10720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110721 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710722}
10723
bncd16676a2016-07-20 16:23:0110724TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610725 HttpRequestInfo request;
10726 request.method = "GET";
bncce36dca22015-04-21 22:11:2310727 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010728 request.traffic_annotation =
10729 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610730
danakj1fd259a02016-04-16 03:17:0910731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710733
[email protected]e22e1362009-11-23 21:31:1210734 MockRead data_reads[] = {
10735 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610736 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210737 };
[email protected]9492e4a2010-02-24 00:58:4610738
10739 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710740 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610741
[email protected]49639fa2011-12-20 23:22:4110742 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610743
tfarina42834112016-09-22 13:38:2010744 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610746
robpercival214763f2016-07-01 23:27:0110747 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610748
bnc691fda62016-08-12 00:43:1610749 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210750 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610751
wezca1070932016-05-26 20:30:5210752 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610753 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10754
10755 std::string response_data;
bnc691fda62016-08-12 00:43:1610756 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110757 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210758}
10759
bncd16676a2016-07-20 16:23:0110760TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510761 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210762 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410763 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110764 UploadFileElementReader::ScopedOverridingContentLengthForTests
10765 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310766
danakj1fd259a02016-04-16 03:17:0910767 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910768 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410769 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710770 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210771 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710772
10773 HttpRequestInfo request;
10774 request.method = "POST";
bncce36dca22015-04-21 22:11:2310775 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710776 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010777 request.traffic_annotation =
10778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710779
danakj1fd259a02016-04-16 03:17:0910780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310782
10783 MockRead data_reads[] = {
10784 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10785 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610786 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310787 };
[email protected]31a2bfe2010-02-09 08:03:3910788 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710789 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310790
[email protected]49639fa2011-12-20 23:22:4110791 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310792
tfarina42834112016-09-22 13:38:2010793 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310795
10796 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110797 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310798
bnc691fda62016-08-12 00:43:1610799 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210800 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310801
maksim.sisove869bf52016-06-23 17:11:5210802 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310803
[email protected]dd3aa792013-07-16 19:10:2310804 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310805}
10806
bncd16676a2016-07-20 16:23:0110807TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510808 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210809 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610810 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810811 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10812 base::WriteFile(temp_file, temp_file_content.c_str(),
10813 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110814 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610815
danakj1fd259a02016-04-16 03:17:0910816 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910817 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410818 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710819 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210820 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710821
10822 HttpRequestInfo request;
10823 request.method = "POST";
bncce36dca22015-04-21 22:11:2310824 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710825 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010826 request.traffic_annotation =
10827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710828
[email protected]999dd8c2013-11-12 06:45:5410829 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610832
[email protected]999dd8c2013-11-12 06:45:5410833 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710834 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610835
[email protected]49639fa2011-12-20 23:22:4110836 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610837
tfarina42834112016-09-22 13:38:2010838 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610840
10841 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110842 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610843
[email protected]dd3aa792013-07-16 19:10:2310844 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610845}
10846
bncd16676a2016-07-20 16:23:0110847TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310848 class FakeUploadElementReader : public UploadElementReader {
10849 public:
Chris Watkins7a41d3552017-12-01 02:13:2710850 FakeUploadElementReader() = default;
10851 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310852
Matt Menkecc1d3a902018-02-05 18:27:3310853 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310854
10855 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310856 int Init(CompletionOnceCallback callback) override {
10857 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310858 return ERR_IO_PENDING;
10859 }
avibf0746c2015-12-09 19:53:1410860 uint64_t GetContentLength() const override { return 0; }
10861 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010862 int Read(IOBuffer* buf,
10863 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310864 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310865 return ERR_FAILED;
10866 }
10867
10868 private:
Matt Menkecc1d3a902018-02-05 18:27:3310869 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310870 };
10871
10872 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910873 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10874 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210875 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310876
10877 HttpRequestInfo request;
10878 request.method = "POST";
bncce36dca22015-04-21 22:11:2310879 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310880 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010881 request.traffic_annotation =
10882 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310883
danakj1fd259a02016-04-16 03:17:0910884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810885 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910886 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310887
10888 StaticSocketDataProvider data;
10889 session_deps_.socket_factory->AddSocketDataProvider(&data);
10890
10891 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010892 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510894 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310895
10896 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310897 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10898 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310899
10900 // Return Init()'s result after the transaction gets destroyed.
10901 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310902 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310903}
10904
[email protected]aeefc9e82010-02-19 16:18:2710905// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110906TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710907 HttpRequestInfo request;
10908 request.method = "GET";
bncce36dca22015-04-21 22:11:2310909 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010910 request.traffic_annotation =
10911 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710912
10913 // First transaction will request a resource and receive a Basic challenge
10914 // with realm="first_realm".
10915 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310916 MockWrite(
10917 "GET / HTTP/1.1\r\n"
10918 "Host: www.example.org\r\n"
10919 "Connection: keep-alive\r\n"
10920 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710921 };
10922 MockRead data_reads1[] = {
10923 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10924 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10925 "\r\n"),
10926 };
10927
bnc691fda62016-08-12 00:43:1610928 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710929 // for first_realm. The server will reject and provide a challenge with
10930 // second_realm.
10931 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310932 MockWrite(
10933 "GET / HTTP/1.1\r\n"
10934 "Host: www.example.org\r\n"
10935 "Connection: keep-alive\r\n"
10936 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10937 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710938 };
10939 MockRead data_reads2[] = {
10940 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10941 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10942 "\r\n"),
10943 };
10944
10945 // This again fails, and goes back to first_realm. Make sure that the
10946 // entry is removed from cache.
10947 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310948 MockWrite(
10949 "GET / HTTP/1.1\r\n"
10950 "Host: www.example.org\r\n"
10951 "Connection: keep-alive\r\n"
10952 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10953 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710954 };
10955 MockRead data_reads3[] = {
10956 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10957 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10958 "\r\n"),
10959 };
10960
10961 // Try one last time (with the correct password) and get the resource.
10962 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310963 MockWrite(
10964 "GET / HTTP/1.1\r\n"
10965 "Host: www.example.org\r\n"
10966 "Connection: keep-alive\r\n"
10967 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10968 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710969 };
10970 MockRead data_reads4[] = {
10971 MockRead("HTTP/1.1 200 OK\r\n"
10972 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010973 "Content-Length: 5\r\n"
10974 "\r\n"
10975 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710976 };
10977
10978 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10979 data_writes1, arraysize(data_writes1));
10980 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10981 data_writes2, arraysize(data_writes2));
10982 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10983 data_writes3, arraysize(data_writes3));
10984 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10985 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710986 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10987 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10988 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10989 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710990
[email protected]49639fa2011-12-20 23:22:4110991 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710992
danakj1fd259a02016-04-16 03:17:0910993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010995
[email protected]aeefc9e82010-02-19 16:18:2710996 // Issue the first request with Authorize headers. There should be a
10997 // password prompt for first_realm waiting to be filled in after the
10998 // transaction completes.
tfarina42834112016-09-22 13:38:2010999 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711001 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111002 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611003 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211004 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411005 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211006 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411007 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311008 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411009 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911010 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711011
11012 // Issue the second request with an incorrect password. There should be a
11013 // password prompt for second_realm waiting to be filled in after the
11014 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111015 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611016 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11017 callback2.callback());
robpercival214763f2016-07-01 23:27:0111018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711019 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111020 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611021 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211022 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411023 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211024 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411025 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311026 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411027 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911028 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711029
11030 // Issue the third request with another incorrect password. There should be
11031 // a password prompt for first_realm waiting to be filled in. If the password
11032 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11033 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111034 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611035 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11036 callback3.callback());
robpercival214763f2016-07-01 23:27:0111037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711038 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111039 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611040 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211041 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411042 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211043 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411044 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311045 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411046 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911047 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711048
11049 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111050 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611051 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11052 callback4.callback());
robpercival214763f2016-07-01 23:27:0111053 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711054 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111055 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611056 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211057 ASSERT_TRUE(response);
11058 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711059}
11060
Bence Béky230ac612017-08-30 19:17:0811061// Regression test for https://crbug.com/754395.
11062TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11063 MockRead data_reads[] = {
11064 MockRead("HTTP/1.1 200 OK\r\n"),
11065 MockRead(kAlternativeServiceHttpHeader),
11066 MockRead("\r\n"),
11067 MockRead("hello world"),
11068 MockRead(SYNCHRONOUS, OK),
11069 };
11070
11071 HttpRequestInfo request;
11072 request.method = "GET";
11073 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011074 request.traffic_annotation =
11075 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811076
11077 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11078 session_deps_.socket_factory->AddSocketDataProvider(&data);
11079
11080 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911081 ssl.ssl_info.cert =
11082 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11083 ASSERT_TRUE(ssl.ssl_info.cert);
11084 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11086
11087 TestCompletionCallback callback;
11088
11089 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11090 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11091
11092 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11094
11095 url::SchemeHostPort test_server(request.url);
11096 HttpServerProperties* http_server_properties =
11097 session->http_server_properties();
11098 EXPECT_TRUE(
11099 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11100
11101 EXPECT_THAT(callback.WaitForResult(), IsOk());
11102
11103 const HttpResponseInfo* response = trans.GetResponseInfo();
11104 ASSERT_TRUE(response);
11105 ASSERT_TRUE(response->headers);
11106 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11107 EXPECT_FALSE(response->was_fetched_via_spdy);
11108 EXPECT_FALSE(response->was_alpn_negotiated);
11109
11110 std::string response_data;
11111 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11112 EXPECT_EQ("hello world", response_data);
11113
11114 EXPECT_TRUE(
11115 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11116}
11117
bncd16676a2016-07-20 16:23:0111118TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211119 MockRead data_reads[] = {
11120 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311121 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211122 MockRead("\r\n"),
11123 MockRead("hello world"),
11124 MockRead(SYNCHRONOUS, OK),
11125 };
11126
11127 HttpRequestInfo request;
11128 request.method = "GET";
bncb26024382016-06-29 02:39:4511129 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011130 request.traffic_annotation =
11131 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211132
11133 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211134 session_deps_.socket_factory->AddSocketDataProvider(&data);
11135
bncb26024382016-06-29 02:39:4511136 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911137 ssl.ssl_info.cert =
11138 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11139 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511140 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11141
bncc958faa2015-07-31 18:14:5211142 TestCompletionCallback callback;
11143
danakj1fd259a02016-04-16 03:17:0911144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211146
tfarina42834112016-09-22 13:38:2011147 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211149
bncb26024382016-06-29 02:39:4511150 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011151 HttpServerProperties* http_server_properties =
11152 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411153 EXPECT_TRUE(
11154 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211155
robpercival214763f2016-07-01 23:27:0111156 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211157
bnc691fda62016-08-12 00:43:1611158 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211159 ASSERT_TRUE(response);
11160 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211161 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11162 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211163 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211164
11165 std::string response_data;
bnc691fda62016-08-12 00:43:1611166 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211167 EXPECT_EQ("hello world", response_data);
11168
zhongyic4de03032017-05-19 04:07:3411169 AlternativeServiceInfoVector alternative_service_info_vector =
11170 http_server_properties->GetAlternativeServiceInfos(test_server);
11171 ASSERT_EQ(1u, alternative_service_info_vector.size());
11172 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11173 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411174 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211175}
11176
bnce3dd56f2016-06-01 10:37:1111177// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111178TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111179 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111180 MockRead data_reads[] = {
11181 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311182 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111183 MockRead("\r\n"),
11184 MockRead("hello world"),
11185 MockRead(SYNCHRONOUS, OK),
11186 };
11187
11188 HttpRequestInfo request;
11189 request.method = "GET";
11190 request.url = GURL("http://www.example.org/");
11191 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011192 request.traffic_annotation =
11193 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111194
11195 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11196 session_deps_.socket_factory->AddSocketDataProvider(&data);
11197
11198 TestCompletionCallback callback;
11199
11200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111202
11203 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011204 HttpServerProperties* http_server_properties =
11205 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411206 EXPECT_TRUE(
11207 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111208
tfarina42834112016-09-22 13:38:2011209 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11211 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111212
bnc691fda62016-08-12 00:43:1611213 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111214 ASSERT_TRUE(response);
11215 ASSERT_TRUE(response->headers);
11216 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11217 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211218 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111219
11220 std::string response_data;
bnc691fda62016-08-12 00:43:1611221 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111222 EXPECT_EQ("hello world", response_data);
11223
zhongyic4de03032017-05-19 04:07:3411224 EXPECT_TRUE(
11225 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111226}
11227
bnca86731e2017-04-17 12:31:2811228// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511229// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111230TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511231 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811232 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511233
bnc8bef8da22016-05-30 01:28:2511234 HttpRequestInfo request;
11235 request.method = "GET";
bncb26024382016-06-29 02:39:4511236 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511237 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011238 request.traffic_annotation =
11239 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511240
11241 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11242 StaticSocketDataProvider first_data;
11243 first_data.set_connect_data(mock_connect);
11244 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511245 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611246 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511247 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511248
11249 MockRead data_reads[] = {
11250 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11251 MockRead(ASYNC, OK),
11252 };
11253 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11254 0);
11255 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11256
11257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11258
bnc525e175a2016-06-20 12:36:4011259 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511260 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111261 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11262 444);
bnc8bef8da22016-05-30 01:28:2511263 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111264 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511265 url::SchemeHostPort(request.url), alternative_service, expiration);
11266
bnc691fda62016-08-12 00:43:1611267 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511268 TestCompletionCallback callback;
11269
tfarina42834112016-09-22 13:38:2011270 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511271 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111272 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511273}
11274
bnce3dd56f2016-06-01 10:37:1111275// Regression test for https://crbug.com/615497:
11276// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111277TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111278 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111279 HttpRequestInfo request;
11280 request.method = "GET";
11281 request.url = GURL("http://www.example.org/");
11282 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011283 request.traffic_annotation =
11284 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111285
11286 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11287 StaticSocketDataProvider first_data;
11288 first_data.set_connect_data(mock_connect);
11289 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11290
11291 MockRead data_reads[] = {
11292 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11293 MockRead(ASYNC, OK),
11294 };
11295 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11296 0);
11297 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11298
11299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11300
bnc525e175a2016-06-20 12:36:4011301 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111302 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111303 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111304 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111305 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111306 url::SchemeHostPort(request.url), alternative_service, expiration);
11307
bnc691fda62016-08-12 00:43:1611308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111309 TestCompletionCallback callback;
11310
tfarina42834112016-09-22 13:38:2011311 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111312 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111313 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111314}
11315
bncd16676a2016-07-20 16:23:0111316TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811317 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011319 HttpServerProperties* http_server_properties =
11320 session->http_server_properties();
bncb26024382016-06-29 02:39:4511321 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111322 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811323 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111324 http_server_properties->SetQuicAlternativeService(
11325 test_server, alternative_service, expiration,
11326 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411327 EXPECT_EQ(
11328 1u,
11329 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811330
11331 // Send a clear header.
11332 MockRead data_reads[] = {
11333 MockRead("HTTP/1.1 200 OK\r\n"),
11334 MockRead("Alt-Svc: clear\r\n"),
11335 MockRead("\r\n"),
11336 MockRead("hello world"),
11337 MockRead(SYNCHRONOUS, OK),
11338 };
11339 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
11340 session_deps_.socket_factory->AddSocketDataProvider(&data);
11341
bncb26024382016-06-29 02:39:4511342 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911343 ssl.ssl_info.cert =
11344 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11345 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11347
bnc4f575852015-10-14 18:35:0811348 HttpRequestInfo request;
11349 request.method = "GET";
bncb26024382016-06-29 02:39:4511350 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011351 request.traffic_annotation =
11352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811353
11354 TestCompletionCallback callback;
11355
bnc691fda62016-08-12 00:43:1611356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811357
tfarina42834112016-09-22 13:38:2011358 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111359 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811360
bnc691fda62016-08-12 00:43:1611361 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211362 ASSERT_TRUE(response);
11363 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811364 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11365 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211366 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811367
11368 std::string response_data;
bnc691fda62016-08-12 00:43:1611369 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811370 EXPECT_EQ("hello world", response_data);
11371
zhongyic4de03032017-05-19 04:07:3411372 EXPECT_TRUE(
11373 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811374}
11375
bncd16676a2016-07-20 16:23:0111376TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211377 MockRead data_reads[] = {
11378 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311379 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11380 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211381 MockRead("hello world"),
11382 MockRead(SYNCHRONOUS, OK),
11383 };
11384
11385 HttpRequestInfo request;
11386 request.method = "GET";
bncb26024382016-06-29 02:39:4511387 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011388 request.traffic_annotation =
11389 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211390
11391 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211392 session_deps_.socket_factory->AddSocketDataProvider(&data);
11393
bncb26024382016-06-29 02:39:4511394 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911395 ssl.ssl_info.cert =
11396 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11397 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511398 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11399
bncc958faa2015-07-31 18:14:5211400 TestCompletionCallback callback;
11401
danakj1fd259a02016-04-16 03:17:0911402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211404
tfarina42834112016-09-22 13:38:2011405 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111406 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211407
bncb26024382016-06-29 02:39:4511408 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011409 HttpServerProperties* http_server_properties =
11410 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411411 EXPECT_TRUE(
11412 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211413
robpercival214763f2016-07-01 23:27:0111414 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211415
bnc691fda62016-08-12 00:43:1611416 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211417 ASSERT_TRUE(response);
11418 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211419 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11420 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211421 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211422
11423 std::string response_data;
bnc691fda62016-08-12 00:43:1611424 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211425 EXPECT_EQ("hello world", response_data);
11426
zhongyic4de03032017-05-19 04:07:3411427 AlternativeServiceInfoVector alternative_service_info_vector =
11428 http_server_properties->GetAlternativeServiceInfos(test_server);
11429 ASSERT_EQ(2u, alternative_service_info_vector.size());
11430
11431 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11432 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411433 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411434 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11435 1234);
11436 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411437 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211438}
11439
bncd16676a2016-07-20 16:23:0111440TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611441 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211442 HostPortPair alternative("alternative.example.org", 443);
11443 std::string origin_url = "https://origin.example.org:443";
11444 std::string alternative_url = "https://alternative.example.org:443";
11445
11446 // Negotiate HTTP/1.1 with alternative.example.org.
11447 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611448 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11450
11451 // HTTP/1.1 data for request.
11452 MockWrite http_writes[] = {
11453 MockWrite("GET / HTTP/1.1\r\n"
11454 "Host: alternative.example.org\r\n"
11455 "Connection: keep-alive\r\n\r\n"),
11456 };
11457
11458 MockRead http_reads[] = {
11459 MockRead("HTTP/1.1 200 OK\r\n"
11460 "Content-Type: text/html; charset=iso-8859-1\r\n"
11461 "Content-Length: 40\r\n\r\n"
11462 "first HTTP/1.1 response from alternative"),
11463 };
11464 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11465 http_writes, arraysize(http_writes));
11466 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11467
11468 StaticSocketDataProvider data_refused;
11469 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11470 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11471
zhongyi3d4a55e72016-04-22 20:36:4611472 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011474 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211475 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111476 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211477 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111478 http_server_properties->SetQuicAlternativeService(
11479 server, alternative_service, expiration,
11480 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211481 // Mark the QUIC alternative service as broken.
11482 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11483
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_TRUE(details.quic_broken);
11498}
11499
bncd16676a2016-07-20 16:23:0111500TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611501 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211502 HostPortPair alternative1("alternative1.example.org", 443);
11503 HostPortPair alternative2("alternative2.example.org", 443);
11504 std::string origin_url = "https://origin.example.org:443";
11505 std::string alternative_url1 = "https://alternative1.example.org:443";
11506 std::string alternative_url2 = "https://alternative2.example.org:443";
11507
11508 // Negotiate HTTP/1.1 with alternative1.example.org.
11509 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611510 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211511 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11512
11513 // HTTP/1.1 data for request.
11514 MockWrite http_writes[] = {
11515 MockWrite("GET / HTTP/1.1\r\n"
11516 "Host: alternative1.example.org\r\n"
11517 "Connection: keep-alive\r\n\r\n"),
11518 };
11519
11520 MockRead http_reads[] = {
11521 MockRead("HTTP/1.1 200 OK\r\n"
11522 "Content-Type: text/html; charset=iso-8859-1\r\n"
11523 "Content-Length: 40\r\n\r\n"
11524 "first HTTP/1.1 response from alternative1"),
11525 };
11526 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11527 http_writes, arraysize(http_writes));
11528 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11529
11530 StaticSocketDataProvider data_refused;
11531 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11532 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11533
danakj1fd259a02016-04-16 03:17:0911534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011535 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211536 session->http_server_properties();
11537
zhongyi3d4a55e72016-04-22 20:36:4611538 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211539 AlternativeServiceInfoVector alternative_service_info_vector;
11540 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11541
bnc3472afd2016-11-17 15:27:2111542 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111543 alternative_service_info_vector.push_back(
11544 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11545 alternative_service1, expiration,
11546 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111547 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111548 alternative_service_info_vector.push_back(
11549 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11550 alternative_service2, expiration,
11551 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211552
11553 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611554 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211555
11556 // Mark one of the QUIC alternative service as broken.
11557 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411558 EXPECT_EQ(2u,
11559 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211560
zhongyi48704c182015-12-07 07:52:0211561 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611562 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211563 request.method = "GET";
11564 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011565 request.traffic_annotation =
11566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11567
zhongyi48704c182015-12-07 07:52:0211568 TestCompletionCallback callback;
11569 NetErrorDetails details;
11570 EXPECT_FALSE(details.quic_broken);
11571
tfarina42834112016-09-22 13:38:2011572 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611573 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211574 EXPECT_FALSE(details.quic_broken);
11575}
11576
bncd16676a2016-07-20 16:23:0111577TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211578 HttpRequestInfo request;
11579 request.method = "GET";
bncb26024382016-06-29 02:39:4511580 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011581 request.traffic_annotation =
11582 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211583
[email protected]d973e99a2012-02-17 21:02:3611584 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211585 StaticSocketDataProvider first_data;
11586 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711587 session_deps_.socket_factory->AddSocketDataProvider(&first_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]564b4912010-03-09 16:30:4211591
11592 MockRead data_reads[] = {
11593 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11594 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611595 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211596 };
11597 StaticSocketDataProvider second_data(
11598 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711599 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211600
danakj1fd259a02016-04-16 03:17:0911601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211602
bnc525e175a2016-06-20 12:36:4011603 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311604 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611605 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111606 // Port must be < 1024, or the header will be ignored (since initial port was
11607 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111608 // Port is ignored by MockConnect anyway.
11609 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11610 666);
bnc7dc7e1b42015-07-28 14:43:1211611 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111612 http_server_properties->SetHttp2AlternativeService(
11613 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211614
bnc691fda62016-08-12 00:43:1611615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111616 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211617
tfarina42834112016-09-22 13:38:2011618 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11620 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211621
bnc691fda62016-08-12 00:43:1611622 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211623 ASSERT_TRUE(response);
11624 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211625 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11626
11627 std::string response_data;
bnc691fda62016-08-12 00:43:1611628 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211629 EXPECT_EQ("hello world", response_data);
11630
zhongyic4de03032017-05-19 04:07:3411631 const AlternativeServiceInfoVector alternative_service_info_vector =
11632 http_server_properties->GetAlternativeServiceInfos(server);
11633 ASSERT_EQ(1u, alternative_service_info_vector.size());
11634 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411635 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411636 EXPECT_TRUE(
11637 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211638}
11639
bnc55ff9da2015-08-19 18:42:3511640// Ensure that we are not allowed to redirect traffic via an alternate protocol
11641// to an unrestricted (port >= 1024) when the original traffic was on a
11642// restricted port (port < 1024). Ensure that we can redirect in all other
11643// cases.
bncd16676a2016-07-20 16:23:0111644TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111645 HttpRequestInfo restricted_port_request;
11646 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511647 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111648 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011649 restricted_port_request.traffic_annotation =
11650 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111651
[email protected]d973e99a2012-02-17 21:02:3611652 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111653 StaticSocketDataProvider first_data;
11654 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711655 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111656
11657 MockRead data_reads[] = {
11658 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11659 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611660 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111661 };
11662 StaticSocketDataProvider second_data(
11663 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711664 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511665 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611666 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511667 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111668
danakj1fd259a02016-04-16 03:17:0911669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111670
bnc525e175a2016-06-20 12:36:4011671 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311672 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111673 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111674 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11675 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211676 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111677 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611678 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011679 expiration);
[email protected]3912662a32011-10-04 00:51:1111680
bnc691fda62016-08-12 00:43:1611681 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111682 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111683
tfarina42834112016-09-22 13:38:2011684 int rv = trans.Start(&restricted_port_request, callback.callback(),
11685 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111687 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111688 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911689}
[email protected]3912662a32011-10-04 00:51:1111690
bnc55ff9da2015-08-19 18:42:3511691// Ensure that we are allowed to redirect traffic via an alternate protocol to
11692// an unrestricted (port >= 1024) when the original traffic was on a restricted
11693// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111694TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711695 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911696
11697 HttpRequestInfo restricted_port_request;
11698 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511699 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911700 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011701 restricted_port_request.traffic_annotation =
11702 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911703
11704 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11705 StaticSocketDataProvider first_data;
11706 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711707 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911708
11709 MockRead data_reads[] = {
11710 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11711 MockRead("hello world"),
11712 MockRead(ASYNC, OK),
11713 };
11714 StaticSocketDataProvider second_data(
11715 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711716 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511717 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611718 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911720
danakj1fd259a02016-04-16 03:17:0911721 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911722
bnc525e175a2016-06-20 12:36:4011723 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911724 session->http_server_properties();
11725 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111726 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11727 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211728 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111729 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611730 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011731 expiration);
[email protected]c54c6962013-02-01 04:53:1911732
bnc691fda62016-08-12 00:43:1611733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911734 TestCompletionCallback callback;
11735
tfarina42834112016-09-22 13:38:2011736 EXPECT_EQ(ERR_IO_PENDING,
11737 trans.Start(&restricted_port_request, callback.callback(),
11738 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911739 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111740 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111741}
11742
bnc55ff9da2015-08-19 18:42:3511743// Ensure that we are not allowed to redirect traffic via an alternate protocol
11744// to an unrestricted (port >= 1024) when the original traffic was on a
11745// restricted port (port < 1024). Ensure that we can redirect in all other
11746// cases.
bncd16676a2016-07-20 16:23:0111747TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111748 HttpRequestInfo restricted_port_request;
11749 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511750 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111751 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011752 restricted_port_request.traffic_annotation =
11753 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111754
[email protected]d973e99a2012-02-17 21:02:3611755 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111756 StaticSocketDataProvider first_data;
11757 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711758 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111759
11760 MockRead data_reads[] = {
11761 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11762 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611763 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111764 };
11765 StaticSocketDataProvider second_data(
11766 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711767 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111768
bncb26024382016-06-29 02:39:4511769 SSLSocketDataProvider ssl(ASYNC, OK);
11770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11771
danakj1fd259a02016-04-16 03:17:0911772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111773
bnc525e175a2016-06-20 12:36:4011774 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311775 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111776 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111777 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11778 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211779 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111780 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611781 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011782 expiration);
[email protected]3912662a32011-10-04 00:51:1111783
bnc691fda62016-08-12 00:43:1611784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111785 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111786
tfarina42834112016-09-22 13:38:2011787 int rv = trans.Start(&restricted_port_request, callback.callback(),
11788 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111790 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111791 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111792}
11793
bnc55ff9da2015-08-19 18:42:3511794// Ensure that we are not allowed to redirect traffic via an alternate protocol
11795// to an unrestricted (port >= 1024) when the original traffic was on a
11796// restricted port (port < 1024). Ensure that we can redirect in all other
11797// cases.
bncd16676a2016-07-20 16:23:0111798TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111799 HttpRequestInfo unrestricted_port_request;
11800 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511801 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111802 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011803 unrestricted_port_request.traffic_annotation =
11804 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111805
[email protected]d973e99a2012-02-17 21:02:3611806 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111807 StaticSocketDataProvider first_data;
11808 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711809 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111810
11811 MockRead data_reads[] = {
11812 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11813 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611814 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111815 };
11816 StaticSocketDataProvider second_data(
11817 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711818 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511819 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611820 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511821 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111822
danakj1fd259a02016-04-16 03:17:0911823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111824
bnc525e175a2016-06-20 12:36:4011825 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311826 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111827 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111828 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11829 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211830 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111831 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611832 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011833 expiration);
[email protected]3912662a32011-10-04 00:51:1111834
bnc691fda62016-08-12 00:43:1611835 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111836 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111837
bnc691fda62016-08-12 00:43:1611838 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011839 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111841 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111842 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111843}
11844
bnc55ff9da2015-08-19 18:42:3511845// Ensure that we are not allowed to redirect traffic via an alternate protocol
11846// to an unrestricted (port >= 1024) when the original traffic was on a
11847// restricted port (port < 1024). Ensure that we can redirect in all other
11848// cases.
bncd16676a2016-07-20 16:23:0111849TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111850 HttpRequestInfo unrestricted_port_request;
11851 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511852 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111853 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011854 unrestricted_port_request.traffic_annotation =
11855 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111856
[email protected]d973e99a2012-02-17 21:02:3611857 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111858 StaticSocketDataProvider first_data;
11859 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711860 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111861
11862 MockRead data_reads[] = {
11863 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11864 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611865 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111866 };
11867 StaticSocketDataProvider second_data(
11868 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711869 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111870
bncb26024382016-06-29 02:39:4511871 SSLSocketDataProvider ssl(ASYNC, OK);
11872 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11873
danakj1fd259a02016-04-16 03:17:0911874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111875
bnc525e175a2016-06-20 12:36:4011876 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311877 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211878 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111879 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11880 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211881 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111882 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611883 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011884 expiration);
[email protected]3912662a32011-10-04 00:51:1111885
bnc691fda62016-08-12 00:43:1611886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111887 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111888
bnc691fda62016-08-12 00:43:1611889 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011890 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111892 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111893 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111894}
11895
bnc55ff9da2015-08-19 18:42:3511896// Ensure that we are not allowed to redirect traffic via an alternate protocol
11897// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11898// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111899TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211900 HttpRequestInfo request;
11901 request.method = "GET";
bncce36dca22015-04-21 22:11:2311902 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011903 request.traffic_annotation =
11904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211905
11906 // The alternate protocol request will error out before we attempt to connect,
11907 // so only the standard HTTP request will try to connect.
11908 MockRead data_reads[] = {
11909 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11910 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611911 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211912 };
11913 StaticSocketDataProvider data(
11914 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711915 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211916
danakj1fd259a02016-04-16 03:17:0911917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211918
bnc525e175a2016-06-20 12:36:4011919 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211920 session->http_server_properties();
11921 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111922 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11923 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211924 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111925 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611926 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211927
bnc691fda62016-08-12 00:43:1611928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211929 TestCompletionCallback callback;
11930
tfarina42834112016-09-22 13:38:2011931 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111932 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211933 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111934 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211935
bnc691fda62016-08-12 00:43:1611936 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211937 ASSERT_TRUE(response);
11938 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211939 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11940
11941 std::string response_data;
bnc691fda62016-08-12 00:43:1611942 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211943 EXPECT_EQ("hello world", response_data);
11944}
11945
bncd16676a2016-07-20 16:23:0111946TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411947 HttpRequestInfo request;
11948 request.method = "GET";
bncb26024382016-06-29 02:39:4511949 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011950 request.traffic_annotation =
11951 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411952
11953 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211954 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311955 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211956 MockRead("\r\n"),
11957 MockRead("hello world"),
11958 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11959 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411960
11961 StaticSocketDataProvider first_transaction(
11962 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711963 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511964 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611965 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511966 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411967
bnc032658ba2016-09-26 18:17:1511968 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411969
bncdf80d44fd2016-07-15 20:27:4111970 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511971 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111972 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411973
bnc42331402016-07-25 13:36:1511974 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111975 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411976 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111977 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411978 };
11979
rch8e6c6c42015-05-01 14:05:1311980 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11981 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711982 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411983
[email protected]d973e99a2012-02-17 21:02:3611984 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511985 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11986 NULL, 0, NULL, 0);
11987 hanging_non_alternate_protocol_socket.set_connect_data(
11988 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711989 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511990 &hanging_non_alternate_protocol_socket);
11991
[email protected]49639fa2011-12-20 23:22:4111992 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411993
danakj1fd259a02016-04-16 03:17:0911994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811995 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911996 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411997
tfarina42834112016-09-22 13:38:2011998 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12000 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412001
12002 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212003 ASSERT_TRUE(response);
12004 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412005 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12006
12007 std::string response_data;
robpercival214763f2016-07-01 23:27:0112008 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412009 EXPECT_EQ("hello world", response_data);
12010
bnc87dcefc2017-05-25 12:47:5812011 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912012 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412013
tfarina42834112016-09-22 13:38:2012014 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12016 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412017
12018 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212019 ASSERT_TRUE(response);
12020 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212021 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312022 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212023 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412024
robpercival214763f2016-07-01 23:27:0112025 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412026 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412027}
12028
bncd16676a2016-07-20 16:23:0112029TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512030 HttpRequestInfo request;
12031 request.method = "GET";
bncb26024382016-06-29 02:39:4512032 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012033 request.traffic_annotation =
12034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512035
bncb26024382016-06-29 02:39:4512036 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512037 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212038 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312039 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212040 MockRead("\r\n"),
12041 MockRead("hello world"),
12042 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12043 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512044 };
12045
bncb26024382016-06-29 02:39:4512046 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
12047 0);
12048 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512049
bncb26024382016-06-29 02:39:4512050 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912051 ssl_http11.ssl_info.cert =
12052 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12053 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12055
12056 // Second transaction starts an alternative and a non-alternative Job.
12057 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612058 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1812059 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
12060 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812061 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12062
12063 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
12064 hanging_socket2.set_connect_data(never_finishing_connect);
12065 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512066
bncb26024382016-06-29 02:39:4512067 // Third transaction starts an alternative and a non-alternative job.
12068 // The non-alternative job hangs, but the alternative one succeeds.
12069 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4112070 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512071 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112072 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512073 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512074 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112075 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512076 };
bnc42331402016-07-25 13:36:1512077 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112078 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512079 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112080 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512081 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112082 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12083 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312084 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512085 };
12086
rch8e6c6c42015-05-01 14:05:1312087 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12088 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712089 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512090
bnc032658ba2016-09-26 18:17:1512091 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512092
mmenkecc2298e2015-12-07 18:20:1812093 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
12094 hanging_socket3.set_connect_data(never_finishing_connect);
12095 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512096
danakj1fd259a02016-04-16 03:17:0912097 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112098 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012099 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512100
tfarina42834112016-09-22 13:38:2012101 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12103 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512104
12105 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212106 ASSERT_TRUE(response);
12107 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512108 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12109
12110 std::string response_data;
robpercival214763f2016-07-01 23:27:0112111 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512112 EXPECT_EQ("hello world", response_data);
12113
[email protected]49639fa2011-12-20 23:22:4112114 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012115 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012116 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512118
[email protected]49639fa2011-12-20 23:22:4112119 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012120 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012121 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512123
robpercival214763f2016-07-01 23:27:0112124 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12125 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512126
12127 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212128 ASSERT_TRUE(response);
12129 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212130 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512131 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212132 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112133 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512134 EXPECT_EQ("hello!", response_data);
12135
12136 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212137 ASSERT_TRUE(response);
12138 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212139 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512140 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212141 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112142 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512143 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512144}
12145
bncd16676a2016-07-20 16:23:0112146TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512147 HttpRequestInfo request;
12148 request.method = "GET";
bncb26024382016-06-29 02:39:4512149 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012150 request.traffic_annotation =
12151 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512152
12153 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212154 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312155 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212156 MockRead("\r\n"),
12157 MockRead("hello world"),
12158 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12159 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512160 };
12161
12162 StaticSocketDataProvider first_transaction(
12163 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712164 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512165
[email protected]8ddf8322012-02-23 18:08:0612166 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912167 ssl.ssl_info.cert =
12168 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12169 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512171
[email protected]d973e99a2012-02-17 21:02:3612172 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512173 StaticSocketDataProvider hanging_alternate_protocol_socket(
12174 NULL, 0, NULL, 0);
12175 hanging_alternate_protocol_socket.set_connect_data(
12176 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712177 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512178 &hanging_alternate_protocol_socket);
12179
bncb26024382016-06-29 02:39:4512180 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1812181 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
12182 NULL, 0);
12183 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512185
[email protected]49639fa2011-12-20 23:22:4112186 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512187
danakj1fd259a02016-04-16 03:17:0912188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812189 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912190 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512191
tfarina42834112016-09-22 13:38:2012192 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12194 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512195
12196 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212197 ASSERT_TRUE(response);
12198 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512199 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12200
12201 std::string response_data;
robpercival214763f2016-07-01 23:27:0112202 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512203 EXPECT_EQ("hello world", response_data);
12204
bnc87dcefc2017-05-25 12:47:5812205 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912206 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512207
tfarina42834112016-09-22 13:38:2012208 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12210 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512211
12212 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212213 ASSERT_TRUE(response);
12214 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512215 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12216 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212217 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512218
robpercival214763f2016-07-01 23:27:0112219 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512220 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512221}
12222
[email protected]631f1322010-04-30 17:59:1112223class CapturingProxyResolver : public ProxyResolver {
12224 public:
Chris Watkins7a41d3552017-12-01 02:13:2712225 CapturingProxyResolver() = default;
12226 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112227
dchengb03027d2014-10-21 12:00:2012228 int GetProxyForURL(const GURL& url,
12229 ProxyInfo* results,
12230 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512231 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012232 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012233 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12234 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212235 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112236 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212237 return OK;
[email protected]631f1322010-04-30 17:59:1112238 }
12239
[email protected]24476402010-07-20 20:55:1712240 const std::vector<GURL>& resolved() const { return resolved_; }
12241
12242 private:
[email protected]631f1322010-04-30 17:59:1112243 std::vector<GURL> resolved_;
12244
12245 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12246};
12247
sammce64b2362015-04-29 03:50:2312248class CapturingProxyResolverFactory : public ProxyResolverFactory {
12249 public:
12250 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12251 : ProxyResolverFactory(false), resolver_(resolver) {}
12252
Lily Houghton99597862018-03-07 16:40:4212253 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12254 std::unique_ptr<ProxyResolver>* resolver,
12255 const net::CompletionCallback& callback,
12256 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912257 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312258 return OK;
12259 }
12260
12261 private:
12262 ProxyResolver* resolver_;
12263};
12264
bnc2e884782016-08-11 19:45:1912265// Test that proxy is resolved using the origin url,
12266// regardless of the alternative server.
12267TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12268 // Configure proxy to bypass www.example.org, which is the origin URL.
12269 ProxyConfig proxy_config;
12270 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12271 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912272 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12273 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912274
12275 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912276 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912277 &capturing_proxy_resolver);
12278
12279 TestNetLog net_log;
12280
Bence Béky53a5aef2018-03-29 21:54:1212281 session_deps_.proxy_resolution_service =
12282 std::make_unique<ProxyResolutionService>(
12283 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12284 &net_log);
bnc2e884782016-08-11 19:45:1912285
12286 session_deps_.net_log = &net_log;
12287
12288 // Configure alternative service with a hostname that is not bypassed by the
12289 // proxy.
12290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12291 HttpServerProperties* http_server_properties =
12292 session->http_server_properties();
12293 url::SchemeHostPort server("https", "www.example.org", 443);
12294 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112295 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912296 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112297 http_server_properties->SetHttp2AlternativeService(
12298 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912299
12300 // Non-alternative job should hang.
12301 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
12302 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
12303 nullptr, 0);
12304 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12305 session_deps_.socket_factory->AddSocketDataProvider(
12306 &hanging_alternate_protocol_socket);
12307
bnc032658ba2016-09-26 18:17:1512308 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912309
12310 HttpRequestInfo request;
12311 request.method = "GET";
12312 request.url = GURL("https://www.example.org/");
12313 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012314 request.traffic_annotation =
12315 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912316
12317 SpdySerializedFrame req(
12318 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12319
12320 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12321
12322 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12323 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12324 MockRead spdy_reads[] = {
12325 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12326 };
12327
12328 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12329 arraysize(spdy_writes));
12330 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12331
12332 TestCompletionCallback callback;
12333
12334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12335
tfarina42834112016-09-22 13:38:2012336 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912337 EXPECT_THAT(callback.GetResult(rv), IsOk());
12338
12339 const HttpResponseInfo* response = trans.GetResponseInfo();
12340 ASSERT_TRUE(response);
12341 ASSERT_TRUE(response->headers);
12342 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12343 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212344 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912345
12346 std::string response_data;
12347 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12348 EXPECT_EQ("hello!", response_data);
12349
12350 // Origin host bypasses proxy, no resolution should have happened.
12351 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12352}
12353
bncd16676a2016-07-20 16:23:0112354TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112355 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212356 proxy_config.set_auto_detect(true);
12357 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112358
sammc5dd160c2015-04-02 02:43:1312359 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912360 session_deps_.proxy_resolution_service =
12361 std::make_unique<ProxyResolutionService>(
12362 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12363 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12364 std::make_unique<CapturingProxyResolverFactory>(
12365 &capturing_proxy_resolver),
12366 nullptr);
vishal.b62985ca92015-04-17 08:45:5112367 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712368 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112369
12370 HttpRequestInfo request;
12371 request.method = "GET";
bncb26024382016-06-29 02:39:4512372 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012373 request.traffic_annotation =
12374 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112375
12376 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212377 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312378 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212379 MockRead("\r\n"),
12380 MockRead("hello world"),
12381 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12382 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112383 };
12384
12385 StaticSocketDataProvider first_transaction(
12386 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712387 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512388 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612389 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512390 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112391
bnc032658ba2016-09-26 18:17:1512392 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112393
bncdf80d44fd2016-07-15 20:27:4112394 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512395 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112396 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312397 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512398 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12399 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312400 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112401 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112402 };
12403
[email protected]d911f1b2010-05-05 22:39:4212404 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12405
bnc42331402016-07-25 13:36:1512406 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112407 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112408 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112409 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12410 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112411 };
12412
rch8e6c6c42015-05-01 14:05:1312413 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12414 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712415 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112416
[email protected]d973e99a2012-02-17 21:02:3612417 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512418 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12419 NULL, 0, NULL, 0);
12420 hanging_non_alternate_protocol_socket.set_connect_data(
12421 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712422 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512423 &hanging_non_alternate_protocol_socket);
12424
[email protected]49639fa2011-12-20 23:22:4112425 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112426
danakj1fd259a02016-04-16 03:17:0912427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812428 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912429 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112430
tfarina42834112016-09-22 13:38:2012431 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112432 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12433 EXPECT_THAT(callback.WaitForResult(), IsOk());
12434
12435 const HttpResponseInfo* response = trans->GetResponseInfo();
12436 ASSERT_TRUE(response);
12437 ASSERT_TRUE(response->headers);
12438 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12439 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212440 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112441
12442 std::string response_data;
12443 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12444 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112445
bnc87dcefc2017-05-25 12:47:5812446 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912447 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112448
tfarina42834112016-09-22 13:38:2012449 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12451 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112452
mmenkea2dcd3bf2016-08-16 21:49:4112453 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212454 ASSERT_TRUE(response);
12455 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212456 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312457 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212458 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112459
robpercival214763f2016-07-01 23:27:0112460 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112461 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512462 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12463 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312464 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312465 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312466 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112467
[email protected]029c83b62013-01-24 05:28:2012468 LoadTimingInfo load_timing_info;
12469 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12470 TestLoadTimingNotReusedWithPac(load_timing_info,
12471 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112472}
[email protected]631f1322010-04-30 17:59:1112473
bncd16676a2016-07-20 16:23:0112474TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812475 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412476 HttpRequestInfo request;
12477 request.method = "GET";
bncb26024382016-06-29 02:39:4512478 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012479 request.traffic_annotation =
12480 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412481
12482 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212483 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312484 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212485 MockRead("\r\n"),
12486 MockRead("hello world"),
12487 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412488 };
12489
12490 StaticSocketDataProvider first_transaction(
12491 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712492 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512493 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612494 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412496
bnc032658ba2016-09-26 18:17:1512497 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412498
bncdf80d44fd2016-07-15 20:27:4112499 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512500 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112501 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412502
bnc42331402016-07-25 13:36:1512503 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112504 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412505 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112506 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412507 };
12508
rch8e6c6c42015-05-01 14:05:1312509 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12510 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712511 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412512
[email protected]83039bb2011-12-09 18:43:5512513 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412514
danakj1fd259a02016-04-16 03:17:0912515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412516
bnc87dcefc2017-05-25 12:47:5812517 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912518 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412519
tfarina42834112016-09-22 13:38:2012520 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112521 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12522 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412523
12524 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212525 ASSERT_TRUE(response);
12526 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412527 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12528
12529 std::string response_data;
robpercival214763f2016-07-01 23:27:0112530 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412531 EXPECT_EQ("hello world", response_data);
12532
12533 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512534 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012535 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412536 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712537 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212538 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812539
bnc87dcefc2017-05-25 12:47:5812540 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912541 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412542
tfarina42834112016-09-22 13:38:2012543 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12545 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412546
12547 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212548 ASSERT_TRUE(response);
12549 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212550 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312551 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212552 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412553
robpercival214763f2016-07-01 23:27:0112554 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412555 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212556}
12557
[email protected]044de0642010-06-17 10:42:1512558// GenerateAuthToken is a mighty big test.
12559// It tests all permutation of GenerateAuthToken behavior:
12560// - Synchronous and Asynchronous completion.
12561// - OK or error on completion.
12562// - Direct connection, non-authenticating proxy, and authenticating proxy.
12563// - HTTP or HTTPS backend (to include proxy tunneling).
12564// - Non-authenticating and authenticating backend.
12565//
[email protected]fe3b7dc2012-02-03 19:52:0912566// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512567// problems generating an auth token for an authenticating proxy, we don't
12568// need to test all permutations of the backend server).
12569//
12570// The test proceeds by going over each of the configuration cases, and
12571// potentially running up to three rounds in each of the tests. The TestConfig
12572// specifies both the configuration for the test as well as the expectations
12573// for the results.
bncd16676a2016-07-20 16:23:0112574TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012575 static const char kServer[] = "http://www.example.com";
12576 static const char kSecureServer[] = "https://www.example.com";
12577 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512578
12579 enum AuthTiming {
12580 AUTH_NONE,
12581 AUTH_SYNC,
12582 AUTH_ASYNC,
12583 };
12584
12585 const MockWrite kGet(
12586 "GET / HTTP/1.1\r\n"
12587 "Host: www.example.com\r\n"
12588 "Connection: keep-alive\r\n\r\n");
12589 const MockWrite kGetProxy(
12590 "GET http://www.example.com/ HTTP/1.1\r\n"
12591 "Host: www.example.com\r\n"
12592 "Proxy-Connection: keep-alive\r\n\r\n");
12593 const MockWrite kGetAuth(
12594 "GET / HTTP/1.1\r\n"
12595 "Host: www.example.com\r\n"
12596 "Connection: keep-alive\r\n"
12597 "Authorization: auth_token\r\n\r\n");
12598 const MockWrite kGetProxyAuth(
12599 "GET http://www.example.com/ HTTP/1.1\r\n"
12600 "Host: www.example.com\r\n"
12601 "Proxy-Connection: keep-alive\r\n"
12602 "Proxy-Authorization: auth_token\r\n\r\n");
12603 const MockWrite kGetAuthThroughProxy(
12604 "GET http://www.example.com/ HTTP/1.1\r\n"
12605 "Host: www.example.com\r\n"
12606 "Proxy-Connection: keep-alive\r\n"
12607 "Authorization: auth_token\r\n\r\n");
12608 const MockWrite kGetAuthWithProxyAuth(
12609 "GET http://www.example.com/ HTTP/1.1\r\n"
12610 "Host: www.example.com\r\n"
12611 "Proxy-Connection: keep-alive\r\n"
12612 "Proxy-Authorization: auth_token\r\n"
12613 "Authorization: auth_token\r\n\r\n");
12614 const MockWrite kConnect(
12615 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712616 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512617 "Proxy-Connection: keep-alive\r\n\r\n");
12618 const MockWrite kConnectProxyAuth(
12619 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712620 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512621 "Proxy-Connection: keep-alive\r\n"
12622 "Proxy-Authorization: auth_token\r\n\r\n");
12623
12624 const MockRead kSuccess(
12625 "HTTP/1.1 200 OK\r\n"
12626 "Content-Type: text/html; charset=iso-8859-1\r\n"
12627 "Content-Length: 3\r\n\r\n"
12628 "Yes");
12629 const MockRead kFailure(
12630 "Should not be called.");
12631 const MockRead kServerChallenge(
12632 "HTTP/1.1 401 Unauthorized\r\n"
12633 "WWW-Authenticate: Mock realm=server\r\n"
12634 "Content-Type: text/html; charset=iso-8859-1\r\n"
12635 "Content-Length: 14\r\n\r\n"
12636 "Unauthorized\r\n");
12637 const MockRead kProxyChallenge(
12638 "HTTP/1.1 407 Unauthorized\r\n"
12639 "Proxy-Authenticate: Mock realm=proxy\r\n"
12640 "Proxy-Connection: close\r\n"
12641 "Content-Type: text/html; charset=iso-8859-1\r\n"
12642 "Content-Length: 14\r\n\r\n"
12643 "Unauthorized\r\n");
12644 const MockRead kProxyConnected(
12645 "HTTP/1.1 200 Connection Established\r\n\r\n");
12646
12647 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12648 // no constructors, but the C++ compiler on Windows warns about
12649 // unspecified data in compound literals. So, moved to using constructors,
12650 // and TestRound's created with the default constructor should not be used.
12651 struct TestRound {
12652 TestRound()
12653 : expected_rv(ERR_UNEXPECTED),
12654 extra_write(NULL),
12655 extra_read(NULL) {
12656 }
12657 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12658 int expected_rv_arg)
12659 : write(write_arg),
12660 read(read_arg),
12661 expected_rv(expected_rv_arg),
12662 extra_write(NULL),
12663 extra_read(NULL) {
12664 }
12665 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12666 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112667 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512668 : write(write_arg),
12669 read(read_arg),
12670 expected_rv(expected_rv_arg),
12671 extra_write(extra_write_arg),
12672 extra_read(extra_read_arg) {
12673 }
12674 MockWrite write;
12675 MockRead read;
12676 int expected_rv;
12677 const MockWrite* extra_write;
12678 const MockRead* extra_read;
12679 };
12680
12681 static const int kNoSSL = 500;
12682
12683 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112684 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112685 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512686 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112687 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112688 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512689 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112690 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512691 int num_auth_rounds;
12692 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612693 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512694 } test_configs[] = {
asankac93076192016-10-03 15:46:0212695 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112696 {__LINE__,
12697 nullptr,
asankac93076192016-10-03 15:46:0212698 AUTH_NONE,
12699 OK,
12700 kServer,
12701 AUTH_NONE,
12702 OK,
12703 1,
12704 kNoSSL,
12705 {TestRound(kGet, kSuccess, OK)}},
12706 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112707 {__LINE__,
12708 nullptr,
asankac93076192016-10-03 15:46:0212709 AUTH_NONE,
12710 OK,
12711 kServer,
12712 AUTH_SYNC,
12713 OK,
12714 2,
12715 kNoSSL,
12716 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512717 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112718 {__LINE__,
12719 nullptr,
asankac93076192016-10-03 15:46:0212720 AUTH_NONE,
12721 OK,
12722 kServer,
12723 AUTH_SYNC,
12724 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612725 3,
12726 kNoSSL,
12727 {TestRound(kGet, kServerChallenge, OK),
12728 TestRound(kGet, kServerChallenge, OK),
12729 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112730 {__LINE__,
12731 nullptr,
asankae2257db2016-10-11 22:03:1612732 AUTH_NONE,
12733 OK,
12734 kServer,
12735 AUTH_SYNC,
12736 ERR_UNSUPPORTED_AUTH_SCHEME,
12737 2,
12738 kNoSSL,
12739 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112740 {__LINE__,
12741 nullptr,
asankae2257db2016-10-11 22:03:1612742 AUTH_NONE,
12743 OK,
12744 kServer,
12745 AUTH_SYNC,
12746 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12747 2,
12748 kNoSSL,
12749 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112750 {__LINE__,
12751 kProxy,
asankae2257db2016-10-11 22:03:1612752 AUTH_SYNC,
12753 ERR_FAILED,
12754 kServer,
12755 AUTH_NONE,
12756 OK,
12757 2,
12758 kNoSSL,
12759 {TestRound(kGetProxy, kProxyChallenge, OK),
12760 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112761 {__LINE__,
12762 kProxy,
asankae2257db2016-10-11 22:03:1612763 AUTH_ASYNC,
12764 ERR_FAILED,
12765 kServer,
12766 AUTH_NONE,
12767 OK,
12768 2,
12769 kNoSSL,
12770 {TestRound(kGetProxy, kProxyChallenge, OK),
12771 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112772 {__LINE__,
12773 nullptr,
asankae2257db2016-10-11 22:03:1612774 AUTH_NONE,
12775 OK,
12776 kServer,
12777 AUTH_SYNC,
12778 ERR_FAILED,
asankac93076192016-10-03 15:46:0212779 2,
12780 kNoSSL,
12781 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612782 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112783 {__LINE__,
12784 nullptr,
asankae2257db2016-10-11 22:03:1612785 AUTH_NONE,
12786 OK,
12787 kServer,
12788 AUTH_ASYNC,
12789 ERR_FAILED,
12790 2,
12791 kNoSSL,
12792 {TestRound(kGet, kServerChallenge, OK),
12793 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112794 {__LINE__,
12795 nullptr,
asankac93076192016-10-03 15:46:0212796 AUTH_NONE,
12797 OK,
12798 kServer,
12799 AUTH_ASYNC,
12800 OK,
12801 2,
12802 kNoSSL,
12803 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512804 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112805 {__LINE__,
12806 nullptr,
asankac93076192016-10-03 15:46:0212807 AUTH_NONE,
12808 OK,
12809 kServer,
12810 AUTH_ASYNC,
12811 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612812 3,
asankac93076192016-10-03 15:46:0212813 kNoSSL,
12814 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612815 // The second round uses a HttpAuthHandlerMock that always succeeds.
12816 TestRound(kGet, kServerChallenge, OK),
12817 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212818 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112819 {__LINE__,
12820 kProxy,
asankac93076192016-10-03 15:46:0212821 AUTH_NONE,
12822 OK,
12823 kServer,
12824 AUTH_NONE,
12825 OK,
12826 1,
12827 kNoSSL,
12828 {TestRound(kGetProxy, kSuccess, OK)}},
12829 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112830 {__LINE__,
12831 kProxy,
asankac93076192016-10-03 15:46:0212832 AUTH_NONE,
12833 OK,
12834 kServer,
12835 AUTH_SYNC,
12836 OK,
12837 2,
12838 kNoSSL,
12839 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512840 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112841 {__LINE__,
12842 kProxy,
asankac93076192016-10-03 15:46:0212843 AUTH_NONE,
12844 OK,
12845 kServer,
12846 AUTH_SYNC,
12847 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612848 3,
asankac93076192016-10-03 15:46:0212849 kNoSSL,
12850 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612851 TestRound(kGetProxy, kServerChallenge, OK),
12852 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112853 {__LINE__,
12854 kProxy,
asankac93076192016-10-03 15:46:0212855 AUTH_NONE,
12856 OK,
12857 kServer,
12858 AUTH_ASYNC,
12859 OK,
12860 2,
12861 kNoSSL,
12862 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512863 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112864 {__LINE__,
12865 kProxy,
asankac93076192016-10-03 15:46:0212866 AUTH_NONE,
12867 OK,
12868 kServer,
12869 AUTH_ASYNC,
12870 ERR_INVALID_AUTH_CREDENTIALS,
12871 2,
12872 kNoSSL,
12873 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612874 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212875 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112876 {__LINE__,
12877 kProxy,
asankac93076192016-10-03 15:46:0212878 AUTH_SYNC,
12879 OK,
12880 kServer,
12881 AUTH_NONE,
12882 OK,
12883 2,
12884 kNoSSL,
12885 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512886 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112887 {__LINE__,
12888 kProxy,
asankac93076192016-10-03 15:46:0212889 AUTH_SYNC,
12890 ERR_INVALID_AUTH_CREDENTIALS,
12891 kServer,
12892 AUTH_NONE,
12893 OK,
12894 2,
12895 kNoSSL,
12896 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612897 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112898 {__LINE__,
12899 kProxy,
asankac93076192016-10-03 15:46:0212900 AUTH_ASYNC,
12901 OK,
12902 kServer,
12903 AUTH_NONE,
12904 OK,
12905 2,
12906 kNoSSL,
12907 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512908 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112909 {__LINE__,
12910 kProxy,
asankac93076192016-10-03 15:46:0212911 AUTH_ASYNC,
12912 ERR_INVALID_AUTH_CREDENTIALS,
12913 kServer,
12914 AUTH_NONE,
12915 OK,
12916 2,
12917 kNoSSL,
12918 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612919 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112920 {__LINE__,
12921 kProxy,
12922 AUTH_ASYNC,
12923 ERR_INVALID_AUTH_CREDENTIALS,
12924 kServer,
12925 AUTH_NONE,
12926 OK,
12927 3,
12928 kNoSSL,
12929 {TestRound(kGetProxy, kProxyChallenge, OK),
12930 TestRound(kGetProxy, kProxyChallenge, OK),
12931 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212932 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112933 {__LINE__,
12934 kProxy,
asankac93076192016-10-03 15:46:0212935 AUTH_SYNC,
12936 OK,
12937 kServer,
12938 AUTH_SYNC,
12939 OK,
12940 3,
12941 kNoSSL,
12942 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512943 TestRound(kGetProxyAuth, kServerChallenge, OK),
12944 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112945 {__LINE__,
12946 kProxy,
asankac93076192016-10-03 15:46:0212947 AUTH_SYNC,
12948 OK,
12949 kServer,
12950 AUTH_SYNC,
12951 ERR_INVALID_AUTH_CREDENTIALS,
12952 3,
12953 kNoSSL,
12954 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512955 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612956 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112957 {__LINE__,
12958 kProxy,
asankac93076192016-10-03 15:46:0212959 AUTH_ASYNC,
12960 OK,
12961 kServer,
12962 AUTH_SYNC,
12963 OK,
12964 3,
12965 kNoSSL,
12966 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512967 TestRound(kGetProxyAuth, kServerChallenge, OK),
12968 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112969 {__LINE__,
12970 kProxy,
asankac93076192016-10-03 15:46:0212971 AUTH_ASYNC,
12972 OK,
12973 kServer,
12974 AUTH_SYNC,
12975 ERR_INVALID_AUTH_CREDENTIALS,
12976 3,
12977 kNoSSL,
12978 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512979 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612980 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112981 {__LINE__,
12982 kProxy,
asankac93076192016-10-03 15:46:0212983 AUTH_SYNC,
12984 OK,
12985 kServer,
12986 AUTH_ASYNC,
12987 OK,
12988 3,
12989 kNoSSL,
12990 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512991 TestRound(kGetProxyAuth, kServerChallenge, OK),
12992 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112993 {__LINE__,
12994 kProxy,
12995 AUTH_SYNC,
12996 ERR_INVALID_AUTH_CREDENTIALS,
12997 kServer,
12998 AUTH_ASYNC,
12999 OK,
13000 4,
13001 kNoSSL,
13002 {TestRound(kGetProxy, kProxyChallenge, OK),
13003 TestRound(kGetProxy, kProxyChallenge, OK),
13004 TestRound(kGetProxyAuth, kServerChallenge, OK),
13005 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13006 {__LINE__,
13007 kProxy,
asankac93076192016-10-03 15:46:0213008 AUTH_SYNC,
13009 OK,
13010 kServer,
13011 AUTH_ASYNC,
13012 ERR_INVALID_AUTH_CREDENTIALS,
13013 3,
13014 kNoSSL,
13015 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513016 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613017 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113018 {__LINE__,
13019 kProxy,
asankac93076192016-10-03 15:46:0213020 AUTH_ASYNC,
13021 OK,
13022 kServer,
13023 AUTH_ASYNC,
13024 OK,
13025 3,
13026 kNoSSL,
13027 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513028 TestRound(kGetProxyAuth, kServerChallenge, OK),
13029 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113030 {__LINE__,
13031 kProxy,
asankac93076192016-10-03 15:46:0213032 AUTH_ASYNC,
13033 OK,
13034 kServer,
13035 AUTH_ASYNC,
13036 ERR_INVALID_AUTH_CREDENTIALS,
13037 3,
13038 kNoSSL,
13039 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513040 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613041 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113042 {__LINE__,
13043 kProxy,
13044 AUTH_ASYNC,
13045 ERR_INVALID_AUTH_CREDENTIALS,
13046 kServer,
13047 AUTH_ASYNC,
13048 ERR_INVALID_AUTH_CREDENTIALS,
13049 4,
13050 kNoSSL,
13051 {TestRound(kGetProxy, kProxyChallenge, OK),
13052 TestRound(kGetProxy, kProxyChallenge, OK),
13053 TestRound(kGetProxyAuth, kServerChallenge, OK),
13054 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213055 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113056 {__LINE__,
13057 nullptr,
asankac93076192016-10-03 15:46:0213058 AUTH_NONE,
13059 OK,
13060 kSecureServer,
13061 AUTH_NONE,
13062 OK,
13063 1,
13064 0,
13065 {TestRound(kGet, kSuccess, OK)}},
13066 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113067 {__LINE__,
13068 nullptr,
asankac93076192016-10-03 15:46:0213069 AUTH_NONE,
13070 OK,
13071 kSecureServer,
13072 AUTH_SYNC,
13073 OK,
13074 2,
13075 0,
13076 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513077 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113078 {__LINE__,
13079 nullptr,
asankac93076192016-10-03 15:46:0213080 AUTH_NONE,
13081 OK,
13082 kSecureServer,
13083 AUTH_SYNC,
13084 ERR_INVALID_AUTH_CREDENTIALS,
13085 2,
13086 0,
asankae2257db2016-10-11 22:03:1613087 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113088 {__LINE__,
13089 nullptr,
asankac93076192016-10-03 15:46:0213090 AUTH_NONE,
13091 OK,
13092 kSecureServer,
13093 AUTH_ASYNC,
13094 OK,
13095 2,
13096 0,
13097 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513098 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113099 {__LINE__,
13100 nullptr,
asankac93076192016-10-03 15:46:0213101 AUTH_NONE,
13102 OK,
13103 kSecureServer,
13104 AUTH_ASYNC,
13105 ERR_INVALID_AUTH_CREDENTIALS,
13106 2,
13107 0,
asankae2257db2016-10-11 22:03:1613108 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213109 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113110 {__LINE__,
13111 kProxy,
asankac93076192016-10-03 15:46:0213112 AUTH_NONE,
13113 OK,
13114 kSecureServer,
13115 AUTH_NONE,
13116 OK,
13117 1,
13118 0,
13119 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13120 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113121 {__LINE__,
13122 kProxy,
asankac93076192016-10-03 15:46:0213123 AUTH_NONE,
13124 OK,
13125 kSecureServer,
13126 AUTH_SYNC,
13127 OK,
13128 2,
13129 0,
13130 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513131 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113132 {__LINE__,
13133 kProxy,
asankac93076192016-10-03 15:46:0213134 AUTH_NONE,
13135 OK,
13136 kSecureServer,
13137 AUTH_SYNC,
13138 ERR_INVALID_AUTH_CREDENTIALS,
13139 2,
13140 0,
13141 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613142 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113143 {__LINE__,
13144 kProxy,
asankac93076192016-10-03 15:46:0213145 AUTH_NONE,
13146 OK,
13147 kSecureServer,
13148 AUTH_ASYNC,
13149 OK,
13150 2,
13151 0,
13152 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513153 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113154 {__LINE__,
13155 kProxy,
asankac93076192016-10-03 15:46:0213156 AUTH_NONE,
13157 OK,
13158 kSecureServer,
13159 AUTH_ASYNC,
13160 ERR_INVALID_AUTH_CREDENTIALS,
13161 2,
13162 0,
13163 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613164 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213165 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113166 {__LINE__,
13167 kProxy,
asankac93076192016-10-03 15:46:0213168 AUTH_SYNC,
13169 OK,
13170 kSecureServer,
13171 AUTH_NONE,
13172 OK,
13173 2,
13174 1,
13175 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513176 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113177 {__LINE__,
13178 kProxy,
asankac93076192016-10-03 15:46:0213179 AUTH_SYNC,
13180 ERR_INVALID_AUTH_CREDENTIALS,
13181 kSecureServer,
13182 AUTH_NONE,
13183 OK,
13184 2,
13185 kNoSSL,
13186 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613187 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113188 {__LINE__,
13189 kProxy,
asankae2257db2016-10-11 22:03:1613190 AUTH_SYNC,
13191 ERR_UNSUPPORTED_AUTH_SCHEME,
13192 kSecureServer,
13193 AUTH_NONE,
13194 OK,
13195 2,
13196 kNoSSL,
13197 {TestRound(kConnect, kProxyChallenge, OK),
13198 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113199 {__LINE__,
13200 kProxy,
asankae2257db2016-10-11 22:03:1613201 AUTH_SYNC,
13202 ERR_UNEXPECTED,
13203 kSecureServer,
13204 AUTH_NONE,
13205 OK,
13206 2,
13207 kNoSSL,
13208 {TestRound(kConnect, kProxyChallenge, OK),
13209 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113210 {__LINE__,
13211 kProxy,
asankac93076192016-10-03 15:46:0213212 AUTH_ASYNC,
13213 OK,
13214 kSecureServer,
13215 AUTH_NONE,
13216 OK,
13217 2,
13218 1,
13219 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513220 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113221 {__LINE__,
13222 kProxy,
asankac93076192016-10-03 15:46:0213223 AUTH_ASYNC,
13224 ERR_INVALID_AUTH_CREDENTIALS,
13225 kSecureServer,
13226 AUTH_NONE,
13227 OK,
13228 2,
13229 kNoSSL,
13230 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613231 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213232 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113233 {__LINE__,
13234 kProxy,
asankac93076192016-10-03 15:46:0213235 AUTH_SYNC,
13236 OK,
13237 kSecureServer,
13238 AUTH_SYNC,
13239 OK,
13240 3,
13241 1,
13242 {TestRound(kConnect, kProxyChallenge, OK),
13243 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13244 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513245 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113246 {__LINE__,
13247 kProxy,
asankac93076192016-10-03 15:46:0213248 AUTH_SYNC,
13249 OK,
13250 kSecureServer,
13251 AUTH_SYNC,
13252 ERR_INVALID_AUTH_CREDENTIALS,
13253 3,
13254 1,
13255 {TestRound(kConnect, kProxyChallenge, OK),
13256 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13257 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613258 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113259 {__LINE__,
13260 kProxy,
asankac93076192016-10-03 15:46:0213261 AUTH_ASYNC,
13262 OK,
13263 kSecureServer,
13264 AUTH_SYNC,
13265 OK,
13266 3,
13267 1,
13268 {TestRound(kConnect, kProxyChallenge, OK),
13269 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13270 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513271 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113272 {__LINE__,
13273 kProxy,
asankac93076192016-10-03 15:46:0213274 AUTH_ASYNC,
13275 OK,
13276 kSecureServer,
13277 AUTH_SYNC,
13278 ERR_INVALID_AUTH_CREDENTIALS,
13279 3,
13280 1,
13281 {TestRound(kConnect, kProxyChallenge, OK),
13282 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13283 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613284 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113285 {__LINE__,
13286 kProxy,
asankac93076192016-10-03 15:46:0213287 AUTH_SYNC,
13288 OK,
13289 kSecureServer,
13290 AUTH_ASYNC,
13291 OK,
13292 3,
13293 1,
13294 {TestRound(kConnect, kProxyChallenge, OK),
13295 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13296 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513297 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113298 {__LINE__,
13299 kProxy,
asankac93076192016-10-03 15:46:0213300 AUTH_SYNC,
13301 OK,
13302 kSecureServer,
13303 AUTH_ASYNC,
13304 ERR_INVALID_AUTH_CREDENTIALS,
13305 3,
13306 1,
13307 {TestRound(kConnect, kProxyChallenge, OK),
13308 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13309 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613310 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113311 {__LINE__,
13312 kProxy,
asankac93076192016-10-03 15:46:0213313 AUTH_ASYNC,
13314 OK,
13315 kSecureServer,
13316 AUTH_ASYNC,
13317 OK,
13318 3,
13319 1,
13320 {TestRound(kConnect, kProxyChallenge, OK),
13321 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13322 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513323 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113324 {__LINE__,
13325 kProxy,
asankac93076192016-10-03 15:46:0213326 AUTH_ASYNC,
13327 OK,
13328 kSecureServer,
13329 AUTH_ASYNC,
13330 ERR_INVALID_AUTH_CREDENTIALS,
13331 3,
13332 1,
13333 {TestRound(kConnect, kProxyChallenge, OK),
13334 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13335 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613336 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113337 {__LINE__,
13338 kProxy,
13339 AUTH_ASYNC,
13340 ERR_INVALID_AUTH_CREDENTIALS,
13341 kSecureServer,
13342 AUTH_ASYNC,
13343 ERR_INVALID_AUTH_CREDENTIALS,
13344 4,
13345 2,
13346 {TestRound(kConnect, kProxyChallenge, OK),
13347 TestRound(kConnect, kProxyChallenge, OK),
13348 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13349 &kServerChallenge),
13350 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513351 };
13352
asanka463ca4262016-11-16 02:34:3113353 for (const auto& test_config : test_configs) {
13354 SCOPED_TRACE(::testing::Message() << "Test config at "
13355 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813356 HttpAuthHandlerMock::Factory* auth_factory(
13357 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713358 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913359 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613360
13361 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513362 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113363 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813364 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13365 std::string auth_challenge = "Mock realm=proxy";
13366 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413367 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13368 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813369 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013370 empty_ssl_info, origin,
13371 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813372 auth_handler->SetGenerateExpectation(
13373 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113374 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813375 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13376 }
[email protected]044de0642010-06-17 10:42:1513377 }
13378 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013379 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513380 std::string auth_challenge = "Mock realm=server";
13381 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413382 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13383 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513384 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013385 empty_ssl_info, origin,
13386 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513387 auth_handler->SetGenerateExpectation(
13388 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113389 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813390 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613391
13392 // The second handler always succeeds. It should only be used where there
13393 // are multiple auth sessions for server auth in the same network
13394 // transaction using the same auth scheme.
13395 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913396 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613397 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13398 empty_ssl_info, origin,
13399 NetLogWithSource());
13400 second_handler->SetGenerateExpectation(true, OK);
13401 auth_factory->AddMockHandler(second_handler.release(),
13402 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513403 }
13404 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913405 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913406 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13407 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513408 } else {
Bence Béky53a5aef2018-03-29 21:54:1213409 session_deps_.proxy_resolution_service =
13410 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513411 }
13412
13413 HttpRequestInfo request;
13414 request.method = "GET";
13415 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1013416 request.traffic_annotation =
13417 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513418
danakj1fd259a02016-04-16 03:17:0913419 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513420
rchcb68dc62015-05-21 04:45:3613421 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13422
13423 std::vector<std::vector<MockRead>> mock_reads(1);
13424 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513425 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213426 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513427 const TestRound& read_write_round = test_config.rounds[round];
13428
13429 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613430 mock_reads.back().push_back(read_write_round.read);
13431 mock_writes.back().push_back(read_write_round.write);
13432
13433 // kProxyChallenge uses Proxy-Connection: close which means that the
13434 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413435 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613436 mock_reads.push_back(std::vector<MockRead>());
13437 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513438 }
13439
rchcb68dc62015-05-21 04:45:3613440 if (read_write_round.extra_read) {
13441 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513442 }
rchcb68dc62015-05-21 04:45:3613443 if (read_write_round.extra_write) {
13444 mock_writes.back().push_back(*read_write_round.extra_write);
13445 }
[email protected]044de0642010-06-17 10:42:1513446
13447 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513448 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713449 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513450 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613451 }
[email protected]044de0642010-06-17 10:42:1513452
danakj1fd259a02016-04-16 03:17:0913453 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613454 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913455 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413456 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813457 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613458 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213459 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613460 }
13461
mmenkecc2298e2015-12-07 18:20:1813462 // Transaction must be created after DataProviders, so it's destroyed before
13463 // they are as well.
13464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13465
rchcb68dc62015-05-21 04:45:3613466 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213467 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613468 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513469 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113470 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513471 int rv;
13472 if (round == 0) {
tfarina42834112016-09-22 13:38:2013473 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513474 } else {
[email protected]49639fa2011-12-20 23:22:4113475 rv = trans.RestartWithAuth(
13476 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513477 }
13478 if (rv == ERR_IO_PENDING)
13479 rv = callback.WaitForResult();
13480
13481 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613482 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013483 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513484 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513485 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13486 continue;
13487 }
13488 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213489 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513490 } else {
wezca1070932016-05-26 20:30:5213491 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613492 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513493 }
13494 }
[email protected]e5ae96a2010-04-14 20:12:4513495 }
13496}
13497
bncd16676a2016-07-20 16:23:0113498TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413499 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413500 HttpAuthHandlerMock::Factory* auth_factory(
13501 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713502 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1213503 session_deps_.proxy_resolution_service =
13504 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713505 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13506 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413507
13508 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13509 auth_handler->set_connection_based(true);
13510 std::string auth_challenge = "Mock realm=server";
13511 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413512 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13513 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913514 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413515 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013516 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813517 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413518
[email protected]c871bce92010-07-15 21:51:1413519 int rv = OK;
13520 const HttpResponseInfo* response = NULL;
13521 HttpRequestInfo request;
13522 request.method = "GET";
13523 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1013524 request.traffic_annotation =
13525 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713526
danakj1fd259a02016-04-16 03:17:0913527 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013528
13529 // Use a TCP Socket Pool with only one connection per group. This is used
13530 // to validate that the TCP socket is not released to the pool between
13531 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213532 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813533 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013534 50, // Max sockets for pool
13535 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113536 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13537 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913538 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213539 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813540 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013541
bnc691fda62016-08-12 00:43:1613542 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113543 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413544
13545 const MockWrite kGet(
13546 "GET / HTTP/1.1\r\n"
13547 "Host: www.example.com\r\n"
13548 "Connection: keep-alive\r\n\r\n");
13549 const MockWrite kGetAuth(
13550 "GET / HTTP/1.1\r\n"
13551 "Host: www.example.com\r\n"
13552 "Connection: keep-alive\r\n"
13553 "Authorization: auth_token\r\n\r\n");
13554
13555 const MockRead kServerChallenge(
13556 "HTTP/1.1 401 Unauthorized\r\n"
13557 "WWW-Authenticate: Mock realm=server\r\n"
13558 "Content-Type: text/html; charset=iso-8859-1\r\n"
13559 "Content-Length: 14\r\n\r\n"
13560 "Unauthorized\r\n");
13561 const MockRead kSuccess(
13562 "HTTP/1.1 200 OK\r\n"
13563 "Content-Type: text/html; charset=iso-8859-1\r\n"
13564 "Content-Length: 3\r\n\r\n"
13565 "Yes");
13566
13567 MockWrite writes[] = {
13568 // First round
13569 kGet,
13570 // Second round
13571 kGetAuth,
13572 // Third round
13573 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013574 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013575 kGetAuth,
13576 // Competing request
13577 kGet,
[email protected]c871bce92010-07-15 21:51:1413578 };
13579 MockRead reads[] = {
13580 // First round
13581 kServerChallenge,
13582 // Second round
13583 kServerChallenge,
13584 // Third round
[email protected]eca50e122010-09-11 14:03:3013585 kServerChallenge,
13586 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413587 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013588 // Competing response
13589 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413590 };
13591 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13592 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713593 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413594
thestig9d3bb0c2015-01-24 00:49:5113595 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013596
13597 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413598 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013599 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413600 if (rv == ERR_IO_PENDING)
13601 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113602 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613603 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213604 ASSERT_TRUE(response);
13605 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813606 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113607 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13608 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413609
[email protected]7ef4cbbb2011-02-06 11:19:1013610 // In between rounds, another request comes in for the same domain.
13611 // It should not be able to grab the TCP socket that trans has already
13612 // claimed.
bnc691fda62016-08-12 00:43:1613613 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113614 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013615 rv = trans_compete.Start(&request, callback_compete.callback(),
13616 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113617 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013618 // callback_compete.WaitForResult at this point would stall forever,
13619 // since the HttpNetworkTransaction does not release the request back to
13620 // the pool until after authentication completes.
13621
13622 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413623 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613624 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413625 if (rv == ERR_IO_PENDING)
13626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113627 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613628 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213629 ASSERT_TRUE(response);
13630 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813631 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113632 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13633 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413634
[email protected]7ef4cbbb2011-02-06 11:19:1013635 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413636 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613637 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413638 if (rv == ERR_IO_PENDING)
13639 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113640 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613641 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213642 ASSERT_TRUE(response);
13643 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813644 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113645 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13646 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013647
[email protected]7ef4cbbb2011-02-06 11:19:1013648 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013649 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613650 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013651 if (rv == ERR_IO_PENDING)
13652 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113653 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613654 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213655 ASSERT_TRUE(response);
13656 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813657 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013658
asanka463ca4262016-11-16 02:34:3113659 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13660 // auth handler should transition to a DONE state in concert with the remote
13661 // server. But that's not something we can test here with a mock handler.
13662 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13663 auth_handler->state());
13664
[email protected]7ef4cbbb2011-02-06 11:19:1013665 // Read the body since the fourth round was successful. This will also
13666 // release the socket back to the pool.
13667 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613668 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013669 if (rv == ERR_IO_PENDING)
13670 rv = callback.WaitForResult();
13671 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613672 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013673 EXPECT_EQ(0, rv);
13674 // There are still 0 idle sockets, since the trans_compete transaction
13675 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813676 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013677
13678 // The competing request can now finish. Wait for the headers and then
13679 // read the body.
13680 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113681 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613682 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013683 if (rv == ERR_IO_PENDING)
13684 rv = callback.WaitForResult();
13685 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613686 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013687 EXPECT_EQ(0, rv);
13688
13689 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813690 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413691}
13692
[email protected]65041fa2010-05-21 06:56:5313693// This tests the case that a request is issued via http instead of spdy after
13694// npn is negotiated.
bncd16676a2016-07-20 16:23:0113695TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313696 HttpRequestInfo request;
13697 request.method = "GET";
bncce36dca22015-04-21 22:11:2313698 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013699 request.traffic_annotation =
13700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313701
13702 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313703 MockWrite(
13704 "GET / HTTP/1.1\r\n"
13705 "Host: www.example.org\r\n"
13706 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313707 };
13708
13709 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213710 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313711 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213712 MockRead("\r\n"),
13713 MockRead("hello world"),
13714 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313715 };
13716
[email protected]8ddf8322012-02-23 18:08:0613717 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613718 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313719
[email protected]bb88e1d32013-05-03 23:11:0713720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313721
13722 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13723 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713724 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313725
[email protected]49639fa2011-12-20 23:22:4113726 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313727
danakj1fd259a02016-04-16 03:17:0913728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313730
tfarina42834112016-09-22 13:38:2013731 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313732
robpercival214763f2016-07-01 23:27:0113733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13734 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313735
bnc691fda62016-08-12 00:43:1613736 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213737 ASSERT_TRUE(response);
13738 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313739 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13740
13741 std::string response_data;
bnc691fda62016-08-12 00:43:1613742 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313743 EXPECT_EQ("hello world", response_data);
13744
13745 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213746 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313747}
[email protected]26ef6582010-06-24 02:30:4713748
bnc55ff9da2015-08-19 18:42:3513749// Simulate the SSL handshake completing with an NPN negotiation followed by an
13750// immediate server closing of the socket.
13751// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113752TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713753 HttpRequestInfo request;
13754 request.method = "GET";
bncce36dca22015-04-21 22:11:2313755 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013756 request.traffic_annotation =
13757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713758
[email protected]8ddf8322012-02-23 18:08:0613759 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613760 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713762
Bence Béky27ad0a12018-02-08 00:35:4813763 SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113764 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713765
13766 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613767 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713768 };
13769
rch8e6c6c42015-05-01 14:05:1313770 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13771 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713772 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713773
[email protected]49639fa2011-12-20 23:22:4113774 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713775
danakj1fd259a02016-04-16 03:17:0913776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713778
tfarina42834112016-09-22 13:38:2013779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13781 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713782}
[email protected]65d34382010-07-01 18:12:2613783
[email protected]795cbf82013-07-22 09:37:2713784// A subclass of HttpAuthHandlerMock that records the request URL when
13785// it gets it. This is needed since the auth handler may get destroyed
13786// before we get a chance to query it.
13787class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13788 public:
13789 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13790
Chris Watkins7a41d3552017-12-01 02:13:2713791 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713792
13793 protected:
dchengb03027d2014-10-21 12:00:2013794 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13795 const HttpRequestInfo* request,
13796 const CompletionCallback& callback,
13797 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713798 *url_ = request->url;
13799 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13800 credentials, request, callback, auth_token);
13801 }
13802
13803 private:
13804 GURL* url_;
13805};
13806
[email protected]8e6441ca2010-08-19 05:56:3813807// Test that if we cancel the transaction as the connection is completing, that
13808// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113809TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813810 // Setup everything about the connection to complete synchronously, so that
13811 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13812 // for is the callback from the HttpStreamRequest.
13813 // Then cancel the transaction.
13814 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613815 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813816 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613817 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13818 MockRead(SYNCHRONOUS, "hello world"),
13819 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813820 };
13821
[email protected]8e6441ca2010-08-19 05:56:3813822 HttpRequestInfo request;
13823 request.method = "GET";
bncce36dca22015-04-21 22:11:2313824 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013825 request.traffic_annotation =
13826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813827
[email protected]bb88e1d32013-05-03 23:11:0713828 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813830 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913831 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713832
[email protected]8e6441ca2010-08-19 05:56:3813833 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13834 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713835 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813836
[email protected]49639fa2011-12-20 23:22:4113837 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813838
vishal.b62985ca92015-04-17 08:45:5113839 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113840 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813842 trans.reset(); // Cancel the transaction here.
13843
fdoray92e35a72016-06-10 15:54:5513844 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013845}
13846
[email protected]ecab6e052014-05-16 14:58:1213847// Test that if a transaction is cancelled after receiving the headers, the
13848// stream is drained properly and added back to the socket pool. The main
13849// purpose of this test is to make sure that an HttpStreamParser can be read
13850// from after the HttpNetworkTransaction and the objects it owns have been
13851// deleted.
13852// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113853TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213854 MockRead data_reads[] = {
13855 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13856 MockRead(ASYNC, "Content-Length: 2\r\n"),
13857 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13858 MockRead(ASYNC, "1"),
13859 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13860 // HttpNetworkTransaction has been deleted.
13861 MockRead(ASYNC, "2"),
13862 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13863 };
13864 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13865 session_deps_.socket_factory->AddSocketDataProvider(&data);
13866
danakj1fd259a02016-04-16 03:17:0913867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213868
13869 {
13870 HttpRequestInfo request;
13871 request.method = "GET";
bncce36dca22015-04-21 22:11:2313872 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013873 request.traffic_annotation =
13874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213875
dcheng48459ac22014-08-26 00:46:4113876 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213877 TestCompletionCallback callback;
13878
tfarina42834112016-09-22 13:38:2013879 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213881 callback.WaitForResult();
13882
13883 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213884 ASSERT_TRUE(response);
13885 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213886 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13887
13888 // The transaction and HttpRequestInfo are deleted.
13889 }
13890
13891 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513892 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213893
13894 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113895 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213896}
13897
[email protected]76a505b2010-08-25 06:23:0013898// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113899TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913900 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913901 ProxyResolutionService::CreateFixedFromPacResult(
13902 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113903 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713904 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013906
[email protected]76a505b2010-08-25 06:23:0013907 HttpRequestInfo request;
13908 request.method = "GET";
bncce36dca22015-04-21 22:11:2313909 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013910 request.traffic_annotation =
13911 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013912
13913 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313914 MockWrite(
13915 "GET http://www.example.org/ HTTP/1.1\r\n"
13916 "Host: www.example.org\r\n"
13917 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013918 };
13919
13920 MockRead data_reads1[] = {
13921 MockRead("HTTP/1.1 200 OK\r\n"),
13922 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13923 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613924 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013925 };
13926
13927 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13928 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713929 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013930
[email protected]49639fa2011-12-20 23:22:4113931 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013932
bnc691fda62016-08-12 00:43:1613933 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913934 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613935 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913936 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13937 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013938
bnc691fda62016-08-12 00:43:1613939 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013941
13942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113943 EXPECT_THAT(rv, IsOk());
[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(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713952 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13953 HostPortPair::FromString("myproxy:70")),
13954 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913955 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13956 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13957 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013958 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[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_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013964}
13965
13966// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113967TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913968 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913969 ProxyResolutionService::CreateFixedFromPacResult(
13970 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113971 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713972 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913973 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013974
[email protected]76a505b2010-08-25 06:23:0013975 HttpRequestInfo request;
13976 request.method = "GET";
bncce36dca22015-04-21 22:11:2313977 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013978 request.traffic_annotation =
13979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013980
13981 // Since we have proxy, should try to establish tunnel.
13982 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713983 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13984 "Host: www.example.org:443\r\n"
13985 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013986
rsleevidb16bb02015-11-12 23:47:1713987 MockWrite("GET / HTTP/1.1\r\n"
13988 "Host: www.example.org\r\n"
13989 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013990 };
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"),
[email protected]8ddf8322012-02-23 18:08:0613998 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013999 };
14000
14001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14002 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714003 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614004 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014006
[email protected]49639fa2011-12-20 23:22:4114007 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014008
bnc691fda62016-08-12 00:43:1614009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914010 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614011 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914012 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14013 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014014
bnc691fda62016-08-12 00:43:1614015 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014017
14018 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114019 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614020 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014021 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014022 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014023 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14024 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014025 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014026 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014027 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14028 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014029
bnc691fda62016-08-12 00:43:1614030 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214031 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014032
14033 EXPECT_TRUE(response->headers->IsKeepAlive());
14034 EXPECT_EQ(200, response->headers->response_code());
14035 EXPECT_EQ(100, response->headers->GetContentLength());
14036 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14037 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714038 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14039 HostPortPair::FromString("myproxy:70")),
14040 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914041 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14042 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14043 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014044
14045 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614046 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014047 TestLoadTimingNotReusedWithPac(load_timing_info,
14048 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014049}
14050
rsleevidb16bb02015-11-12 23:47:1714051// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14052// literal host.
bncd16676a2016-07-20 16:23:0114053TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914054 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914055 ProxyResolutionService::CreateFixedFromPacResult(
14056 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714057 BoundTestNetLog log;
14058 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914059 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714060
14061 HttpRequestInfo request;
14062 request.method = "GET";
14063 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1014064 request.traffic_annotation =
14065 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714066
14067 // Since we have proxy, should try to establish tunnel.
14068 MockWrite data_writes1[] = {
14069 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
14070 "Host: [::1]:443\r\n"
14071 "Proxy-Connection: keep-alive\r\n\r\n"),
14072
14073 MockWrite("GET / HTTP/1.1\r\n"
14074 "Host: [::1]\r\n"
14075 "Connection: keep-alive\r\n\r\n"),
14076 };
14077
14078 MockRead data_reads1[] = {
14079 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14080
14081 MockRead("HTTP/1.1 200 OK\r\n"),
14082 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14083 MockRead("Content-Length: 100\r\n\r\n"),
14084 MockRead(SYNCHRONOUS, OK),
14085 };
14086
14087 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14088 data_writes1, arraysize(data_writes1));
14089 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14090 SSLSocketDataProvider ssl(ASYNC, OK);
14091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14092
14093 TestCompletionCallback callback1;
14094
bnc691fda62016-08-12 00:43:1614095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714096
bnc691fda62016-08-12 00:43:1614097 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714099
14100 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114101 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714102 TestNetLogEntry::List entries;
14103 log.GetEntries(&entries);
14104 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014105 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14106 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714107 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014108 entries, pos,
14109 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14110 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714111
bnc691fda62016-08-12 00:43:1614112 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214113 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714114
14115 EXPECT_TRUE(response->headers->IsKeepAlive());
14116 EXPECT_EQ(200, response->headers->response_code());
14117 EXPECT_EQ(100, response->headers->GetContentLength());
14118 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14119 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714120 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14121 HostPortPair::FromString("myproxy:70")),
14122 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714123
14124 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614125 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714126 TestLoadTimingNotReusedWithPac(load_timing_info,
14127 CONNECT_TIMING_HAS_SSL_TIMES);
14128}
14129
[email protected]76a505b2010-08-25 06:23:0014130// Test a basic HTTPS GET request through a proxy, but the server hangs up
14131// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114132TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914133 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14134 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114135 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714136 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014138
[email protected]76a505b2010-08-25 06:23:0014139 HttpRequestInfo request;
14140 request.method = "GET";
bncce36dca22015-04-21 22:11:2314141 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014142 request.traffic_annotation =
14143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014144
14145 // Since we have proxy, should try to establish tunnel.
14146 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714147 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14148 "Host: www.example.org:443\r\n"
14149 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014150
rsleevidb16bb02015-11-12 23:47:1714151 MockWrite("GET / HTTP/1.1\r\n"
14152 "Host: www.example.org\r\n"
14153 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014154 };
14155
14156 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014157 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614158 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014159 };
14160
14161 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14162 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714163 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614164 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014166
[email protected]49639fa2011-12-20 23:22:4114167 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014168
bnc691fda62016-08-12 00:43:1614169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014170
bnc691fda62016-08-12 00:43:1614171 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014173
14174 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114175 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614176 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014177 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014178 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014179 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14180 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014181 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014182 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014183 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14184 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014185}
14186
[email protected]749eefa82010-09-13 22:14:0314187// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114188TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114189 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914190 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114191 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314192
bnc42331402016-07-25 13:36:1514193 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114194 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314195 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114196 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314197 };
14198
rch8e6c6c42015-05-01 14:05:1314199 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
14200 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714201 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314202
[email protected]8ddf8322012-02-23 18:08:0614203 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614204 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714205 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314206
danakj1fd259a02016-04-16 03:17:0914207 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314208
14209 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314210 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014211 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414212 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714213 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214214 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314215
14216 HttpRequestInfo request;
14217 request.method = "GET";
bncce36dca22015-04-21 22:11:2314218 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014219 request.traffic_annotation =
14220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314221
14222 // This is the important line that marks this as a preconnect.
14223 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14224
bnc691fda62016-08-12 00:43:1614225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314226
[email protected]41d64e82013-07-03 22:44:2614227 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014228 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14230 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314231}
14232
[email protected]73b8dd222010-11-11 19:55:2414233// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614234// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214235void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714236 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914237 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714238 request_info.url = GURL("https://www.example.com/");
14239 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914240 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014241 request_info.traffic_annotation =
14242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714243
[email protected]8ddf8322012-02-23 18:08:0614244 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914245 MockWrite data_writes[] = {
14246 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414247 };
ttuttle859dc7a2015-04-23 19:42:2914248 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0714249 session_deps_.socket_factory->AddSocketDataProvider(&data);
14250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414251
danakj1fd259a02016-04-16 03:17:0914252 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414254
[email protected]49639fa2011-12-20 23:22:4114255 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014256 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914257 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414258 rv = callback.WaitForResult();
14259 ASSERT_EQ(error, rv);
14260}
14261
bncd16676a2016-07-20 16:23:0114262TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414263 // Just check a grab bag of cert errors.
14264 static const int kErrors[] = {
14265 ERR_CERT_COMMON_NAME_INVALID,
14266 ERR_CERT_AUTHORITY_INVALID,
14267 ERR_CERT_DATE_INVALID,
14268 };
14269 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614270 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14271 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414272 }
14273}
14274
[email protected]bd0b6772011-01-11 19:59:3014275// Ensure that a client certificate is removed from the SSL client auth
14276// cache when:
14277// 1) No proxy is involved.
14278// 2) TLS False Start is disabled.
14279// 3) The initial TLS handshake requests a client certificate.
14280// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114281TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914282 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714283 request_info.url = GURL("https://www.example.com/");
14284 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914285 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014286 request_info.traffic_annotation =
14287 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714288
[email protected]bd0b6772011-01-11 19:59:3014289 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114290 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014291
14292 // [ssl_]data1 contains the data for the first SSL handshake. When a
14293 // CertificateRequest is received for the first time, the handshake will
14294 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914295 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014296 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714297 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914298 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714299 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014300
14301 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14302 // False Start is not being used, the result of the SSL handshake will be
14303 // returned as part of the SSLClientSocket::Connect() call. This test
14304 // matches the result of a server sending a handshake_failure alert,
14305 // rather than a Finished message, because it requires a client
14306 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914307 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014308 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914310 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014312
14313 // [ssl_]data3 contains the data for the third SSL handshake. When a
14314 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214315 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14316 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014317 // of the HttpNetworkTransaction. Because this test failure is due to
14318 // requiring a client certificate, this fallback handshake should also
14319 // fail.
ttuttle859dc7a2015-04-23 19:42:2914320 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014321 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914323 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714324 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014325
[email protected]80c75f682012-05-26 16:22:1714326 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14327 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214328 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14329 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714330 // of the HttpNetworkTransaction. Because this test failure is due to
14331 // requiring a client certificate, this fallback handshake should also
14332 // fail.
ttuttle859dc7a2015-04-23 19:42:2914333 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714334 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914336 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714337 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714338
danakj1fd259a02016-04-16 03:17:0914339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014341
[email protected]bd0b6772011-01-11 19:59:3014342 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114343 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014344 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114345 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014346
14347 // Complete the SSL handshake, which should abort due to requiring a
14348 // client certificate.
14349 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114350 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014351
14352 // Indicate that no certificate should be supplied. From the perspective
14353 // of SSLClientCertCache, NULL is just as meaningful as a real
14354 // certificate, so this is the same as supply a
14355 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614356 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114357 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014358
14359 // Ensure the certificate was added to the client auth cache before
14360 // allowing the connection to continue restarting.
14361 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414362 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114363 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414364 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214365 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014366
14367 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714368 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14369 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114371 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014372
14373 // Ensure that the client certificate is removed from the cache on a
14374 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114375 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414376 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014377}
14378
14379// Ensure that a client certificate is removed from the SSL client auth
14380// cache when:
14381// 1) No proxy is involved.
14382// 2) TLS False Start is enabled.
14383// 3) The initial TLS handshake requests a client certificate.
14384// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114385TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914386 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714387 request_info.url = GURL("https://www.example.com/");
14388 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914389 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014390 request_info.traffic_annotation =
14391 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714392
[email protected]bd0b6772011-01-11 19:59:3014393 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114394 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014395
14396 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14397 // return successfully after reading up to the peer's Certificate message.
14398 // This is to allow the caller to call SSLClientSocket::Write(), which can
14399 // enqueue application data to be sent in the same packet as the
14400 // ChangeCipherSpec and Finished messages.
14401 // The actual handshake will be finished when SSLClientSocket::Read() is
14402 // called, which expects to process the peer's ChangeCipherSpec and
14403 // Finished messages. If there was an error negotiating with the peer,
14404 // such as due to the peer requiring a client certificate when none was
14405 // supplied, the alert sent by the peer won't be processed until Read() is
14406 // called.
14407
14408 // Like the non-False Start case, when a client certificate is requested by
14409 // the peer, the handshake is aborted during the Connect() call.
14410 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914411 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014412 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714413 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914414 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714415 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014416
14417 // When a client certificate is supplied, Connect() will not be aborted
14418 // when the peer requests the certificate. Instead, the handshake will
14419 // artificially succeed, allowing the caller to write the HTTP request to
14420 // the socket. The handshake messages are not processed until Read() is
14421 // called, which then detects that the handshake was aborted, due to the
14422 // peer sending a handshake_failure because it requires a client
14423 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914424 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014425 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914427 MockRead data2_reads[] = {
14428 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014429 };
ttuttle859dc7a2015-04-23 19:42:2914430 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714431 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014432
14433 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714434 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14435 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914436 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014437 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914439 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714440 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014441
[email protected]80c75f682012-05-26 16:22:1714442 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14443 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914444 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714445 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914447 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714448 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714449
[email protected]7799de12013-05-30 05:52:5114450 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914451 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114452 ssl_data5.cert_request_info = cert_request.get();
14453 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914454 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114455 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14456
danakj1fd259a02016-04-16 03:17:0914457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014459
[email protected]bd0b6772011-01-11 19:59:3014460 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114461 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014462 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114463 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014464
14465 // Complete the SSL handshake, which should abort due to requiring a
14466 // client certificate.
14467 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114468 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014469
14470 // Indicate that no certificate should be supplied. From the perspective
14471 // of SSLClientCertCache, NULL is just as meaningful as a real
14472 // certificate, so this is the same as supply a
14473 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614474 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114475 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014476
14477 // Ensure the certificate was added to the client auth cache before
14478 // allowing the connection to continue restarting.
14479 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414480 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114481 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414482 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214483 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014484
[email protected]bd0b6772011-01-11 19:59:3014485 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714486 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14487 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014488 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114489 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014490
14491 // Ensure that the client certificate is removed from the cache on a
14492 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114493 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414494 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014495}
14496
[email protected]8c405132011-01-11 22:03:1814497// Ensure that a client certificate is removed from the SSL client auth
14498// cache when:
14499// 1) An HTTPS proxy is involved.
14500// 3) The HTTPS proxy requests a client certificate.
14501// 4) The client supplies an invalid/unacceptable certificate for the
14502// proxy.
14503// The test is repeated twice, first for connecting to an HTTPS endpoint,
14504// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114505TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914506 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14507 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114508 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714509 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814510
14511 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114512 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814513
14514 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14515 // [ssl_]data[1-3]. Rather than represending the endpoint
14516 // (www.example.com:443), they represent failures with the HTTPS proxy
14517 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914518 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814519 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714520 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914521 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714522 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814523
ttuttle859dc7a2015-04-23 19:42:2914524 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814525 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914527 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714528 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814529
[email protected]80c75f682012-05-26 16:22:1714530 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14531#if 0
ttuttle859dc7a2015-04-23 19:42:2914532 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814533 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714534 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914535 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714536 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714537#endif
[email protected]8c405132011-01-11 22:03:1814538
ttuttle859dc7a2015-04-23 19:42:2914539 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814540 requests[0].url = GURL("https://www.example.com/");
14541 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914542 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014543 requests[0].traffic_annotation =
14544 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814545
14546 requests[1].url = GURL("http://www.example.com/");
14547 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914548 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014549 requests[1].traffic_annotation =
14550 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814551
14552 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714553 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814556
14557 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114558 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014559 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114560 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814561
14562 // Complete the SSL handshake, which should abort due to requiring a
14563 // client certificate.
14564 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114565 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814566
14567 // Indicate that no certificate should be supplied. From the perspective
14568 // of SSLClientCertCache, NULL is just as meaningful as a real
14569 // certificate, so this is the same as supply a
14570 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614571 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114572 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814573
14574 // Ensure the certificate was added to the client auth cache before
14575 // allowing the connection to continue restarting.
14576 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414577 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114578 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414579 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214580 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814581 // Ensure the certificate was NOT cached for the endpoint. This only
14582 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114583 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414584 HostPortPair("www.example.com", 443), &client_cert,
14585 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814586
14587 // Restart the handshake. This will consume ssl_data2, which fails, and
14588 // then consume ssl_data3, which should also fail. The result code is
14589 // checked against what ssl_data3 should return.
14590 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114591 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814592
14593 // Now that the new handshake has failed, ensure that the client
14594 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114595 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414596 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114597 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414598 HostPortPair("www.example.com", 443), &client_cert,
14599 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814600 }
14601}
14602
bncd16676a2016-07-20 16:23:0114603TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614604 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914605 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614607
bnc032658ba2016-09-26 18:17:1514608 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614609
bncdf80d44fd2016-07-15 20:27:4114610 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914611 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814612 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114613 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714614 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614615 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114616 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614617 };
bnc42331402016-07-25 13:36:1514618 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114619 SpdySerializedFrame host1_resp_body(
14620 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514621 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114622 SpdySerializedFrame host2_resp_body(
14623 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614624 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114625 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14626 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314627 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614628 };
14629
eroman36d84e54432016-03-17 03:23:0214630 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214631 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314632 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14633 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714634 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614635
[email protected]aa22b242011-11-16 18:58:2914636 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614637 HttpRequestInfo request1;
14638 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314639 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614640 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014641 request1.traffic_annotation =
14642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014643 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614644
tfarina42834112016-09-22 13:38:2014645 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14647 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614648
14649 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214650 ASSERT_TRUE(response);
14651 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214652 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614653
14654 std::string response_data;
robpercival214763f2016-07-01 23:27:0114655 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614656 EXPECT_EQ("hello!", response_data);
14657
bnca4d611d2016-09-22 19:55:3714658 // Preload mail.example.com into HostCache.
14659 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014660 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614661 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014662 std::unique_ptr<HostResolver::Request> request;
14663 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14664 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014665 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714667 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114668 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614669
14670 HttpRequestInfo request2;
14671 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714672 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614673 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014674 request2.traffic_annotation =
14675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014676 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614677
tfarina42834112016-09-22 13:38:2014678 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14680 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614681
14682 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214683 ASSERT_TRUE(response);
14684 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214685 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614686 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214687 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114688 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614689 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614690}
14691
bncd16676a2016-07-20 16:23:0114692TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214693 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914694 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214696
bnc032658ba2016-09-26 18:17:1514697 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214698
bncdf80d44fd2016-07-15 20:27:4114699 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914700 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814701 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114702 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714703 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214704 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114705 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214706 };
bnc42331402016-07-25 13:36:1514707 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114708 SpdySerializedFrame host1_resp_body(
14709 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514710 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114711 SpdySerializedFrame host2_resp_body(
14712 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214713 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114714 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14715 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314716 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214717 };
14718
eroman36d84e54432016-03-17 03:23:0214719 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214720 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314721 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14722 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714723 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214724
14725 TestCompletionCallback callback;
14726 HttpRequestInfo request1;
14727 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314728 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214729 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014730 request1.traffic_annotation =
14731 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014732 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214733
tfarina42834112016-09-22 13:38:2014734 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14736 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214737
14738 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214739 ASSERT_TRUE(response);
14740 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214741 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214742
14743 std::string response_data;
robpercival214763f2016-07-01 23:27:0114744 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214745 EXPECT_EQ("hello!", response_data);
14746
14747 HttpRequestInfo request2;
14748 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714749 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214750 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014751 request2.traffic_annotation =
14752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014753 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214754
tfarina42834112016-09-22 13:38:2014755 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14757 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214758
14759 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214760 ASSERT_TRUE(response);
14761 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214762 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214763 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214764 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114765 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214766 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214767}
14768
bnc8016c1f2017-03-31 02:11:2914769// Regression test for https://crbug.com/546991.
14770// The server might not be able to serve an IP pooled request, and might send a
14771// 421 Misdirected Request response status to indicate this.
14772// HttpNetworkTransaction should reset the request and retry without IP pooling.
14773TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14774 // Two hosts resolve to the same IP address.
14775 const std::string ip_addr = "1.2.3.4";
14776 IPAddress ip;
14777 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14778 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14779
Jeremy Roman0579ed62017-08-29 15:56:1914780 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914781 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14782 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14783
14784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14785
14786 // Two requests on the first connection.
14787 SpdySerializedFrame req1(
14788 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14789 spdy_util_.UpdateWithStreamDestruction(1);
14790 SpdySerializedFrame req2(
14791 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14792 SpdySerializedFrame rst(
14793 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14794 MockWrite writes1[] = {
14795 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14796 CreateMockWrite(rst, 6),
14797 };
14798
14799 // The first one succeeds, the second gets error 421 Misdirected Request.
14800 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14801 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14802 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714803 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914804 SpdySerializedFrame resp2(
14805 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14806 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14807 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14808
14809 MockConnect connect1(ASYNC, OK, peer_addr);
14810 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14811 arraysize(writes1));
14812 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14813
14814 AddSSLSocketData();
14815
14816 // Retry the second request on a second connection.
14817 SpdyTestUtil spdy_util2;
14818 SpdySerializedFrame req3(
14819 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14820 MockWrite writes2[] = {
14821 CreateMockWrite(req3, 0),
14822 };
14823
14824 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14825 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14826 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14827 MockRead(ASYNC, 0, 3)};
14828
14829 MockConnect connect2(ASYNC, OK, peer_addr);
14830 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14831 arraysize(writes2));
14832 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14833
14834 AddSSLSocketData();
14835
14836 // Preload mail.example.org into HostCache.
14837 HostPortPair host_port("mail.example.org", 443);
14838 HostResolver::RequestInfo resolve_info(host_port);
14839 AddressList ignored;
14840 std::unique_ptr<HostResolver::Request> request;
14841 TestCompletionCallback callback;
14842 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14843 &ignored, callback.callback(),
14844 &request, NetLogWithSource());
14845 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14846 rv = callback.WaitForResult();
14847 EXPECT_THAT(rv, IsOk());
14848
14849 HttpRequestInfo request1;
14850 request1.method = "GET";
14851 request1.url = GURL("https://www.example.org/");
14852 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014853 request1.traffic_annotation =
14854 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914855 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14856
14857 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14859 rv = callback.WaitForResult();
14860 EXPECT_THAT(rv, IsOk());
14861
14862 const HttpResponseInfo* response = trans1.GetResponseInfo();
14863 ASSERT_TRUE(response);
14864 ASSERT_TRUE(response->headers);
14865 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14866 EXPECT_TRUE(response->was_fetched_via_spdy);
14867 EXPECT_TRUE(response->was_alpn_negotiated);
14868 std::string response_data;
14869 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14870 EXPECT_EQ("hello!", response_data);
14871
14872 HttpRequestInfo request2;
14873 request2.method = "GET";
14874 request2.url = GURL("https://mail.example.org/");
14875 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014876 request2.traffic_annotation =
14877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914878 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14879
14880 BoundTestNetLog log;
14881 rv = trans2.Start(&request2, callback.callback(), log.bound());
14882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14883 rv = callback.WaitForResult();
14884 EXPECT_THAT(rv, IsOk());
14885
14886 response = trans2.GetResponseInfo();
14887 ASSERT_TRUE(response);
14888 ASSERT_TRUE(response->headers);
14889 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14890 EXPECT_TRUE(response->was_fetched_via_spdy);
14891 EXPECT_TRUE(response->was_alpn_negotiated);
14892 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14893 EXPECT_EQ("hello!", response_data);
14894
14895 TestNetLogEntry::List entries;
14896 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914897 ExpectLogContainsSomewhere(
14898 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914899 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914900}
14901
14902// Test that HTTP 421 responses are properly returned to the caller if received
14903// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14904// portions of the response.
14905TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14906 // Two hosts resolve to the same IP address.
14907 const std::string ip_addr = "1.2.3.4";
14908 IPAddress ip;
14909 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14910 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14911
Jeremy Roman0579ed62017-08-29 15:56:1914912 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914913 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14914 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14915
14916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14917
14918 // Two requests on the first connection.
14919 SpdySerializedFrame req1(
14920 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14921 spdy_util_.UpdateWithStreamDestruction(1);
14922 SpdySerializedFrame req2(
14923 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14924 SpdySerializedFrame rst(
14925 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14926 MockWrite writes1[] = {
14927 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14928 CreateMockWrite(rst, 6),
14929 };
14930
14931 // The first one succeeds, the second gets error 421 Misdirected Request.
14932 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14933 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14934 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714935 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914936 SpdySerializedFrame resp2(
14937 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14938 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14939 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14940
14941 MockConnect connect1(ASYNC, OK, peer_addr);
14942 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14943 arraysize(writes1));
14944 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14945
14946 AddSSLSocketData();
14947
14948 // Retry the second request on a second connection. It returns 421 Misdirected
14949 // Retry again.
14950 SpdyTestUtil spdy_util2;
14951 SpdySerializedFrame req3(
14952 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14953 MockWrite writes2[] = {
14954 CreateMockWrite(req3, 0),
14955 };
14956
14957 SpdySerializedFrame resp3(
14958 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14959 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14960 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14961 MockRead(ASYNC, 0, 3)};
14962
14963 MockConnect connect2(ASYNC, OK, peer_addr);
14964 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14965 arraysize(writes2));
14966 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14967
14968 AddSSLSocketData();
14969
14970 // Preload mail.example.org into HostCache.
14971 HostPortPair host_port("mail.example.org", 443);
14972 HostResolver::RequestInfo resolve_info(host_port);
14973 AddressList ignored;
14974 std::unique_ptr<HostResolver::Request> request;
14975 TestCompletionCallback callback;
14976 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14977 &ignored, callback.callback(),
14978 &request, NetLogWithSource());
14979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14980 rv = callback.WaitForResult();
14981 EXPECT_THAT(rv, IsOk());
14982
14983 HttpRequestInfo request1;
14984 request1.method = "GET";
14985 request1.url = GURL("https://www.example.org/");
14986 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014987 request1.traffic_annotation =
14988 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914989 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14990
14991 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14993 rv = callback.WaitForResult();
14994 EXPECT_THAT(rv, IsOk());
14995
14996 const HttpResponseInfo* response = trans1.GetResponseInfo();
14997 ASSERT_TRUE(response);
14998 ASSERT_TRUE(response->headers);
14999 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15000 EXPECT_TRUE(response->was_fetched_via_spdy);
15001 EXPECT_TRUE(response->was_alpn_negotiated);
15002 std::string response_data;
15003 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15004 EXPECT_EQ("hello!", response_data);
15005
15006 HttpRequestInfo request2;
15007 request2.method = "GET";
15008 request2.url = GURL("https://mail.example.org/");
15009 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015010 request2.traffic_annotation =
15011 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915012 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15013
15014 BoundTestNetLog log;
15015 rv = trans2.Start(&request2, callback.callback(), log.bound());
15016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15017 rv = callback.WaitForResult();
15018 EXPECT_THAT(rv, IsOk());
15019
15020 // After a retry, the 421 Misdirected Request is reported back up to the
15021 // caller.
15022 response = trans2.GetResponseInfo();
15023 ASSERT_TRUE(response);
15024 ASSERT_TRUE(response->headers);
15025 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15026 EXPECT_TRUE(response->was_fetched_via_spdy);
15027 EXPECT_TRUE(response->was_alpn_negotiated);
15028 EXPECT_TRUE(response->ssl_info.cert);
15029 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15030 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915031}
15032
bnc6dcd8192017-05-25 20:11:5015033class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4615034 public:
15035 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5015036 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2715037 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4615038
dchengb03027d2014-10-21 12:00:2015039 int ResolveFromCache(const RequestInfo& info,
15040 AddressList* addresses,
tfarina42834112016-09-22 13:38:2015041 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5015042 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4015043 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5015044 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4615045 return rv;
15046 }
15047
[email protected]e3ceb682011-06-28 23:55:4615048 private:
[email protected]e3ceb682011-06-28 23:55:4615049 const HostPortPair host_port_;
15050};
15051
bncd16676a2016-07-20 16:23:0115052TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315053 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4615054 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915055 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3715056 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0915057 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615058
bnc032658ba2016-09-26 18:17:1515059 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615060
bncdf80d44fd2016-07-15 20:27:4115061 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915062 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815063 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4115064 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715065 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615066 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115067 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615068 };
bnc42331402016-07-25 13:36:1515069 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115070 SpdySerializedFrame host1_resp_body(
15071 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1515072 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115073 SpdySerializedFrame host2_resp_body(
15074 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615075 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115076 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15077 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315078 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615079 };
15080
eroman36d84e54432016-03-17 03:23:0215081 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215082 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1315083 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
15084 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0715085 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615086
[email protected]aa22b242011-11-16 18:58:2915087 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615088 HttpRequestInfo request1;
15089 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315090 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615091 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015092 request1.traffic_annotation =
15093 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015094 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615095
tfarina42834112016-09-22 13:38:2015096 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15098 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615099
15100 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215101 ASSERT_TRUE(response);
15102 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215103 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615104
15105 std::string response_data;
robpercival214763f2016-07-01 23:27:0115106 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615107 EXPECT_EQ("hello!", response_data);
15108
15109 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715110 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615111 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015112 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015113 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15114 &ignored, callback.callback(),
15115 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715117 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115118 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615119
15120 HttpRequestInfo request2;
15121 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715122 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615123 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(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615127
tfarina42834112016-09-22 13:38:2015128 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15130 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615131
15132 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215133 ASSERT_TRUE(response);
15134 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215135 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615136 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215137 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115138 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615139 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615140}
15141
bncd16676a2016-07-20 16:23:0115142TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315143 const std::string https_url = "https://www.example.org:8080/";
15144 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415145
15146 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115147 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915148 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415149
15150 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115151 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415152 };
15153
bnc42331402016-07-25 13:36:1515154 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115155 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15156 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915157 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415158
rch8e6c6c42015-05-01 14:05:1315159 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15160 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415161 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715162 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415163
15164 // HTTP GET for the HTTP URL
15165 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315166 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415167 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315168 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415169 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415170 };
15171
15172 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315173 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15174 MockRead(ASYNC, 2, "hello"),
15175 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415176 };
15177
rch8e6c6c42015-05-01 14:05:1315178 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15179 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0415180
[email protected]8450d722012-07-02 19:14:0415181 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615182 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715183 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15184 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15185 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415186
danakj1fd259a02016-04-16 03:17:0915187 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415188
15189 // Start the first transaction to set up the SpdySession
15190 HttpRequestInfo request1;
15191 request1.method = "GET";
15192 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415193 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015194 request1.traffic_annotation =
15195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015196 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415197 TestCompletionCallback callback1;
15198 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015199 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515200 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415201
robpercival214763f2016-07-01 23:27:0115202 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415203 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15204
15205 // Now, start the HTTP request
15206 HttpRequestInfo request2;
15207 request2.method = "GET";
15208 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415209 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015210 request2.traffic_annotation =
15211 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015212 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415213 TestCompletionCallback callback2;
15214 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015215 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515216 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415217
robpercival214763f2016-07-01 23:27:0115218 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415219 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15220}
15221
bnc5452e2a2015-05-08 16:27:4215222// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15223// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115224TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515225 url::SchemeHostPort server("https", "www.example.org", 443);
15226 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215227
bnc8bef8da22016-05-30 01:28:2515228 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215229 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615230 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215231 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15232
15233 // No data should be read from the alternative, because HTTP/1.1 is
15234 // negotiated.
15235 StaticSocketDataProvider data;
15236 session_deps_.socket_factory->AddSocketDataProvider(&data);
15237
15238 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615239 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215240 // mocked. This way the request relies on the alternate Job.
15241 StaticSocketDataProvider data_refused;
15242 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15243 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15244
zhongyi3d4a55e72016-04-22 20:36:4615245 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915246 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015247 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215248 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115249 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215250 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115251 http_server_properties->SetHttp2AlternativeService(
15252 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215253
bnc5452e2a2015-05-08 16:27:4215254 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215256 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515257 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1015258 request.traffic_annotation =
15259 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215260 TestCompletionCallback callback;
15261
15262 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215263 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015264 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215265 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215266}
15267
bnc40448a532015-05-11 19:13:1415268// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615269// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415270// succeeds, the request should succeed, even if the latter fails because
15271// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115272TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515273 url::SchemeHostPort server("https", "www.example.org", 443);
15274 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415275
15276 // Negotiate HTTP/1.1 with alternative.
15277 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615278 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415279 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15280
15281 // No data should be read from the alternative, because HTTP/1.1 is
15282 // negotiated.
15283 StaticSocketDataProvider data;
15284 session_deps_.socket_factory->AddSocketDataProvider(&data);
15285
zhongyi3d4a55e72016-04-22 20:36:4615286 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415287 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615288 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415289 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15290
15291 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515292 MockWrite("GET / HTTP/1.1\r\n"
15293 "Host: www.example.org\r\n"
15294 "Connection: keep-alive\r\n\r\n"),
15295 MockWrite("GET /second HTTP/1.1\r\n"
15296 "Host: www.example.org\r\n"
15297 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415298 };
15299
15300 MockRead http_reads[] = {
15301 MockRead("HTTP/1.1 200 OK\r\n"),
15302 MockRead("Content-Type: text/html\r\n"),
15303 MockRead("Content-Length: 6\r\n\r\n"),
15304 MockRead("foobar"),
15305 MockRead("HTTP/1.1 200 OK\r\n"),
15306 MockRead("Content-Type: text/html\r\n"),
15307 MockRead("Content-Length: 7\r\n\r\n"),
15308 MockRead("another"),
15309 };
15310 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15311 http_writes, arraysize(http_writes));
15312 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15313
zhongyi3d4a55e72016-04-22 20:36:4615314 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915315 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015316 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415317 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115318 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215319 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115320 http_server_properties->SetHttp2AlternativeService(
15321 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415322
15323 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15324 HttpRequestInfo request1;
15325 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515326 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415327 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015328 request1.traffic_annotation =
15329 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415330 TestCompletionCallback callback1;
15331
tfarina42834112016-09-22 13:38:2015332 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415333 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115334 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415335
15336 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215337 ASSERT_TRUE(response1);
15338 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415339 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15340
15341 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115342 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415343 EXPECT_EQ("foobar", response_data1);
15344
15345 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15346 // for alternative service.
15347 EXPECT_TRUE(
15348 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15349
zhongyi3d4a55e72016-04-22 20:36:4615350 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415351 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615352 // to server.
bnc40448a532015-05-11 19:13:1415353 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15354 HttpRequestInfo request2;
15355 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515356 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415357 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015358 request2.traffic_annotation =
15359 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415360 TestCompletionCallback callback2;
15361
tfarina42834112016-09-22 13:38:2015362 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415363 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115364 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415365
15366 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215367 ASSERT_TRUE(response2);
15368 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415369 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15370
15371 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115372 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415373 EXPECT_EQ("another", response_data2);
15374}
15375
bnc5452e2a2015-05-08 16:27:4215376// Alternative service requires HTTP/2 (or SPDY), but there is already a
15377// HTTP/1.1 socket open to the alternative server. That socket should not be
15378// used.
bncd16676a2016-07-20 16:23:0115379TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615380 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215381 HostPortPair alternative("alternative.example.org", 443);
15382 std::string origin_url = "https://origin.example.org:443";
15383 std::string alternative_url = "https://alternative.example.org:443";
15384
15385 // Negotiate HTTP/1.1 with alternative.example.org.
15386 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615387 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15389
15390 // HTTP/1.1 data for |request1| and |request2|.
15391 MockWrite http_writes[] = {
15392 MockWrite(
15393 "GET / HTTP/1.1\r\n"
15394 "Host: alternative.example.org\r\n"
15395 "Connection: keep-alive\r\n\r\n"),
15396 MockWrite(
15397 "GET / HTTP/1.1\r\n"
15398 "Host: alternative.example.org\r\n"
15399 "Connection: keep-alive\r\n\r\n"),
15400 };
15401
15402 MockRead http_reads[] = {
15403 MockRead(
15404 "HTTP/1.1 200 OK\r\n"
15405 "Content-Type: text/html; charset=iso-8859-1\r\n"
15406 "Content-Length: 40\r\n\r\n"
15407 "first HTTP/1.1 response from alternative"),
15408 MockRead(
15409 "HTTP/1.1 200 OK\r\n"
15410 "Content-Type: text/html; charset=iso-8859-1\r\n"
15411 "Content-Length: 41\r\n\r\n"
15412 "second HTTP/1.1 response from alternative"),
15413 };
15414 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15415 http_writes, arraysize(http_writes));
15416 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15417
15418 // This test documents that an alternate Job should not pool to an already
15419 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615420 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215421 StaticSocketDataProvider data_refused;
15422 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15423 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15424
zhongyi3d4a55e72016-04-22 20:36:4615425 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015427 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215428 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115429 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215430 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115431 http_server_properties->SetHttp2AlternativeService(
15432 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215433
15434 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215435 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615436 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215437 request1.method = "GET";
15438 request1.url = GURL(alternative_url);
15439 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015440 request1.traffic_annotation =
15441 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215442 TestCompletionCallback callback1;
15443
tfarina42834112016-09-22 13:38:2015444 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115445 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615446 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215447 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215448 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215449 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215450 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215451 EXPECT_FALSE(response1->was_fetched_via_spdy);
15452 std::string response_data1;
bnc691fda62016-08-12 00:43:1615453 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215454 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15455
15456 // Request for origin.example.org, which has an alternative service. This
15457 // will start two Jobs: the alternative looks for connections to pool to,
15458 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615459 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215460 // this request fails.
bnc5452e2a2015-05-08 16:27:4215461 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615462 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215463 request2.method = "GET";
15464 request2.url = GURL(origin_url);
15465 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015466 request2.traffic_annotation =
15467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215468 TestCompletionCallback callback2;
15469
tfarina42834112016-09-22 13:38:2015470 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115471 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215472
15473 // Another transaction to alternative. This is to test that the HTTP/1.1
15474 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215475 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615476 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215477 request3.method = "GET";
15478 request3.url = GURL(alternative_url);
15479 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015480 request3.traffic_annotation =
15481 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215482 TestCompletionCallback callback3;
15483
tfarina42834112016-09-22 13:38:2015484 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115485 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615486 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215487 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215488 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215489 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215490 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215491 EXPECT_FALSE(response3->was_fetched_via_spdy);
15492 std::string response_data3;
bnc691fda62016-08-12 00:43:1615493 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215494 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15495}
15496
bncd16676a2016-07-20 16:23:0115497TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315498 const std::string https_url = "https://www.example.org:8080/";
15499 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415500
rdsmithebb50aa2015-11-12 03:44:3815501 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115502 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815503
[email protected]8450d722012-07-02 19:14:0415504 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315505 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115506 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415507 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115508 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915509 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115510 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215511 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915512
15513 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915514 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715515 req2_block[kHttp2MethodHeader] = "GET";
15516 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15517 req2_block[kHttp2SchemeHeader] = "http";
15518 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115519 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515520 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415521
15522 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115523 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15524 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415525 };
15526
bncdf80d44fd2016-07-15 20:27:4115527 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515528 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115529 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515530 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115531 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15532 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815533 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115534 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815535 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515536 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115537 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315538 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115539 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315540 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115541 CreateMockRead(wrapped_resp1, 4),
15542 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315543 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115544 CreateMockRead(resp2, 8),
15545 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315546 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15547 };
[email protected]8450d722012-07-02 19:14:0415548
mmenke666a6fea2015-12-19 04:16:3315549 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15550 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415551 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715552 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415553
Lily Houghton8c2f97d2018-01-22 05:06:5915554 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915555 ProxyResolutionService::CreateFixedFromPacResult(
15556 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115557 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715558 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415559 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615560 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315561 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415562 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615563 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15565 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415566
danakj1fd259a02016-04-16 03:17:0915567 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415568
15569 // Start the first transaction to set up the SpdySession
15570 HttpRequestInfo request1;
15571 request1.method = "GET";
15572 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415573 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015574 request1.traffic_annotation =
15575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015576 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415577 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015578 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415579
mmenke666a6fea2015-12-19 04:16:3315580 // This pause is a hack to avoid running into https://crbug.com/497228.
15581 data1.RunUntilPaused();
15582 base::RunLoop().RunUntilIdle();
15583 data1.Resume();
robpercival214763f2016-07-01 23:27:0115584 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415585 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15586
[email protected]f6c63db52013-02-02 00:35:2215587 LoadTimingInfo load_timing_info1;
15588 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15589 TestLoadTimingNotReusedWithPac(load_timing_info1,
15590 CONNECT_TIMING_HAS_SSL_TIMES);
15591
mmenke666a6fea2015-12-19 04:16:3315592 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415593 HttpRequestInfo request2;
15594 request2.method = "GET";
15595 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415596 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015597 request2.traffic_annotation =
15598 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015599 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415600 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015601 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415602
mmenke666a6fea2015-12-19 04:16:3315603 // This pause is a hack to avoid running into https://crbug.com/497228.
15604 data1.RunUntilPaused();
15605 base::RunLoop().RunUntilIdle();
15606 data1.Resume();
robpercival214763f2016-07-01 23:27:0115607 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315608
[email protected]8450d722012-07-02 19:14:0415609 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215610
15611 LoadTimingInfo load_timing_info2;
15612 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15613 // The established SPDY sessions is considered reused by the HTTP request.
15614 TestLoadTimingReusedWithPac(load_timing_info2);
15615 // HTTP requests over a SPDY session should have a different connection
15616 // socket_log_id than requests over a tunnel.
15617 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415618}
15619
[email protected]2d88e7d2012-07-19 17:55:1715620// Test that in the case where we have a SPDY session to a SPDY proxy
15621// that we do not pool other origins that resolve to the same IP when
15622// the certificate does not match the new origin.
15623// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115624TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315625 const std::string url1 = "http://www.example.org/";
15626 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715627 const std::string ip_addr = "1.2.3.4";
15628
rdsmithebb50aa2015-11-12 03:44:3815629 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115630 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815631
[email protected]2d88e7d2012-07-19 17:55:1715632 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615633 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315634 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115635 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515636 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715637
15638 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115639 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715640 };
15641
bnc42331402016-07-25 13:36:1515642 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115643 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715644 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115645 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15646 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715647 };
15648
mmenke666a6fea2015-12-19 04:16:3315649 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15650 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215651 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915652 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715653 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15654 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315655 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715656
15657 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115658 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915659 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715660
15661 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115662 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715663 };
15664
bnc42331402016-07-25 13:36:1515665 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115666 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15667 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315668 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715669
mmenke666a6fea2015-12-19 04:16:3315670 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15671 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715672 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315673 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715674
15675 // Set up a proxy config that sends HTTP requests to a proxy, and
15676 // all others direct.
15677 ProxyConfig proxy_config;
15678 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915679 session_deps_.proxy_resolution_service =
15680 std::make_unique<ProxyResolutionService>(
15681 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15682 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15683 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715684
bncce36dca22015-04-21 22:11:2315685 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615686 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715687 // Load a valid cert. Note, that this does not need to
15688 // be valid for proxy because the MockSSLClientSocket does
15689 // not actually verify it. But SpdySession will use this
15690 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915691 ssl1.ssl_info.cert =
15692 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15693 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315694 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15695 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715696
15697 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615698 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315699 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15700 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715701
Jeremy Roman0579ed62017-08-29 15:56:1915702 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315703 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715704 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715705
danakj1fd259a02016-04-16 03:17:0915706 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715707
15708 // Start the first transaction to set up the SpdySession
15709 HttpRequestInfo request1;
15710 request1.method = "GET";
15711 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715712 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015713 request1.traffic_annotation =
15714 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015715 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715716 TestCompletionCallback callback1;
15717 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015718 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315719 // This pause is a hack to avoid running into https://crbug.com/497228.
15720 data1.RunUntilPaused();
15721 base::RunLoop().RunUntilIdle();
15722 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715723
robpercival214763f2016-07-01 23:27:0115724 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715725 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15726
15727 // Now, start the HTTP request
15728 HttpRequestInfo request2;
15729 request2.method = "GET";
15730 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715731 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015732 request2.traffic_annotation =
15733 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015734 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715735 TestCompletionCallback callback2;
15736 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015737 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515738 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715739
15740 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115741 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715742 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15743}
15744
[email protected]85f97342013-04-17 06:12:2415745// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15746// error) in SPDY session, removes the socket from pool and closes the SPDY
15747// session. Verify that new url's from the same HttpNetworkSession (and a new
15748// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115749TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315750 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415751
15752 MockRead reads1[] = {
15753 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15754 };
15755
mmenke11eb5152015-06-09 14:50:5015756 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415757
bncdf80d44fd2016-07-15 20:27:4115758 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915759 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415760 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115761 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415762 };
15763
bnc42331402016-07-25 13:36:1515764 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115765 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415766 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115767 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15768 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415769 };
15770
mmenke11eb5152015-06-09 14:50:5015771 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15772 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415773
[email protected]85f97342013-04-17 06:12:2415774 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615775 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415778
15779 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615780 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015781 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15782 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415783
danakj1fd259a02016-04-16 03:17:0915784 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015785 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415786
15787 // Start the first transaction to set up the SpdySession and verify that
15788 // connection was closed.
15789 HttpRequestInfo request1;
15790 request1.method = "GET";
15791 request1.url = GURL(https_url);
15792 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015793 request1.traffic_annotation =
15794 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015795 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415796 TestCompletionCallback callback1;
15797 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015798 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115799 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415800
15801 // Now, start the second request and make sure it succeeds.
15802 HttpRequestInfo request2;
15803 request2.method = "GET";
15804 request2.url = GURL(https_url);
15805 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015806 request2.traffic_annotation =
15807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015808 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415809 TestCompletionCallback callback2;
15810 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015811 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415812
robpercival214763f2016-07-01 23:27:0115813 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415814 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15815}
15816
bncd16676a2016-07-20 16:23:0115817TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315818 ClientSocketPoolManager::set_max_sockets_per_group(
15819 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15820 ClientSocketPoolManager::set_max_sockets_per_pool(
15821 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15822
15823 // Use two different hosts with different IPs so they don't get pooled.
15824 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15825 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315827
15828 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615829 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315830 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615831 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315832 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15833 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15834
bncdf80d44fd2016-07-15 20:27:4115835 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915836 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315837 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115838 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315839 };
bnc42331402016-07-25 13:36:1515840 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115841 SpdySerializedFrame host1_resp_body(
15842 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315843 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115844 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915845 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315846 };
15847
rdsmithebb50aa2015-11-12 03:44:3815848 // Use a separate test instance for the separate SpdySession that will be
15849 // created.
bncd16676a2016-07-20 16:23:0115850 SpdyTestUtil spdy_util_2;
Bence Béky53a5aef2018-03-29 21:54:1215851 SequencedSocketData spdy1_data(spdy1_reads, arraysize(spdy1_reads),
15852 spdy1_writes, arraysize(spdy1_writes));
15853 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0315854
bncdf80d44fd2016-07-15 20:27:4115855 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915856 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315857 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115858 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315859 };
bnc42331402016-07-25 13:36:1515860 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115861 SpdySerializedFrame host2_resp_body(
15862 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315863 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115864 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915865 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315866 };
15867
Bence Béky53a5aef2018-03-29 21:54:1215868 SequencedSocketData spdy2_data(spdy2_reads, arraysize(spdy2_reads),
15869 spdy2_writes, arraysize(spdy2_writes));
15870 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0315871
15872 MockWrite http_write[] = {
15873 MockWrite("GET / HTTP/1.1\r\n"
15874 "Host: www.a.com\r\n"
15875 "Connection: keep-alive\r\n\r\n"),
15876 };
15877
15878 MockRead http_read[] = {
15879 MockRead("HTTP/1.1 200 OK\r\n"),
15880 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15881 MockRead("Content-Length: 6\r\n\r\n"),
15882 MockRead("hello!"),
15883 };
15884 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15885 http_write, arraysize(http_write));
15886 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15887
15888 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415889 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15890 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315891 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615892 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315893
15894 TestCompletionCallback callback;
15895 HttpRequestInfo request1;
15896 request1.method = "GET";
15897 request1.url = GURL("https://www.a.com/");
15898 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015899 request1.traffic_annotation =
15900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815901 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915902 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315903
tfarina42834112016-09-22 13:38:2015904 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15906 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315907
15908 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215909 ASSERT_TRUE(response);
15910 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215911 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315912 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215913 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315914
15915 std::string response_data;
robpercival214763f2016-07-01 23:27:0115916 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315917 EXPECT_EQ("hello!", response_data);
15918 trans.reset();
15919 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615920 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315921
15922 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415923 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15924 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315925 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615926 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315927 HttpRequestInfo request2;
15928 request2.method = "GET";
15929 request2.url = GURL("https://www.b.com/");
15930 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015931 request2.traffic_annotation =
15932 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815933 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915934 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315935
tfarina42834112016-09-22 13:38:2015936 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15938 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315939
15940 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215941 ASSERT_TRUE(response);
15942 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215943 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315944 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215945 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115946 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315947 EXPECT_EQ("hello!", response_data);
15948 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615949 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315950 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615951 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315952
15953 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415954 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15955 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315956 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615957 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315958 HttpRequestInfo request3;
15959 request3.method = "GET";
15960 request3.url = GURL("http://www.a.com/");
15961 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015962 request3.traffic_annotation =
15963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815964 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915965 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315966
tfarina42834112016-09-22 13:38:2015967 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15969 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315970
15971 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215972 ASSERT_TRUE(response);
15973 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315974 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15975 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215976 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115977 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315978 EXPECT_EQ("hello!", response_data);
15979 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615980 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315981 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615982 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315983}
15984
bncd16676a2016-07-20 16:23:0115985TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415986 HttpRequestInfo request;
15987 request.method = "GET";
bncce36dca22015-04-21 22:11:2315988 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015989 request.traffic_annotation =
15990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415991
danakj1fd259a02016-04-16 03:17:0915992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415994
ttuttled9dbc652015-09-29 20:00:5915995 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415996 StaticSocketDataProvider data;
15997 data.set_connect_data(mock_connect);
15998 session_deps_.socket_factory->AddSocketDataProvider(&data);
15999
16000 TestCompletionCallback callback;
16001
tfarina42834112016-09-22 13:38:2016002 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416004
16005 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116006 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416007
[email protected]79e1fd62013-06-20 06:50:0416008 // We don't care whether this succeeds or fails, but it shouldn't crash.
16009 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616010 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716011
16012 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616013 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716014 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116015 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916016
16017 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616018 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916019 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416020}
16021
bncd16676a2016-07-20 16:23:0116022TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416023 HttpRequestInfo request;
16024 request.method = "GET";
bncce36dca22015-04-21 22:11:2316025 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016026 request.traffic_annotation =
16027 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416028
danakj1fd259a02016-04-16 03:17:0916029 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416031
ttuttled9dbc652015-09-29 20:00:5916032 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416033 StaticSocketDataProvider data;
16034 data.set_connect_data(mock_connect);
16035 session_deps_.socket_factory->AddSocketDataProvider(&data);
16036
16037 TestCompletionCallback callback;
16038
tfarina42834112016-09-22 13:38:2016039 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416041
16042 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116043 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416044
[email protected]79e1fd62013-06-20 06:50:0416045 // We don't care whether this succeeds or fails, but it shouldn't crash.
16046 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616047 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716048
16049 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616050 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716051 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116052 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916053
16054 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616055 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916056 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416057}
16058
bncd16676a2016-07-20 16:23:0116059TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416060 HttpRequestInfo request;
16061 request.method = "GET";
bncce36dca22015-04-21 22:11:2316062 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016063 request.traffic_annotation =
16064 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416065
danakj1fd259a02016-04-16 03:17:0916066 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616067 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416068
16069 MockWrite data_writes[] = {
16070 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16071 };
16072 MockRead data_reads[] = {
16073 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16074 };
16075
16076 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16077 data_writes, arraysize(data_writes));
16078 session_deps_.socket_factory->AddSocketDataProvider(&data);
16079
16080 TestCompletionCallback callback;
16081
tfarina42834112016-09-22 13:38:2016082 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416084
16085 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116086 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416087
[email protected]79e1fd62013-06-20 06:50:0416088 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616089 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416090 EXPECT_TRUE(request_headers.HasHeader("Host"));
16091}
16092
bncd16676a2016-07-20 16:23:0116093TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416094 HttpRequestInfo request;
16095 request.method = "GET";
bncce36dca22015-04-21 22:11:2316096 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016097 request.traffic_annotation =
16098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416099
danakj1fd259a02016-04-16 03:17:0916100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616101 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416102
16103 MockWrite data_writes[] = {
16104 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16105 };
16106 MockRead data_reads[] = {
16107 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16108 };
16109
16110 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16111 data_writes, arraysize(data_writes));
16112 session_deps_.socket_factory->AddSocketDataProvider(&data);
16113
16114 TestCompletionCallback callback;
16115
tfarina42834112016-09-22 13:38:2016116 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416118
16119 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116120 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416121
[email protected]79e1fd62013-06-20 06:50:0416122 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616123 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416124 EXPECT_TRUE(request_headers.HasHeader("Host"));
16125}
16126
bncd16676a2016-07-20 16:23:0116127TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416128 HttpRequestInfo request;
16129 request.method = "GET";
bncce36dca22015-04-21 22:11:2316130 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016131 request.traffic_annotation =
16132 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416133
danakj1fd259a02016-04-16 03:17:0916134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416136
16137 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316138 MockWrite(
16139 "GET / HTTP/1.1\r\n"
16140 "Host: www.example.org\r\n"
16141 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416142 };
16143 MockRead data_reads[] = {
16144 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16145 };
16146
16147 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16148 data_writes, arraysize(data_writes));
16149 session_deps_.socket_factory->AddSocketDataProvider(&data);
16150
16151 TestCompletionCallback callback;
16152
tfarina42834112016-09-22 13:38:2016153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416155
16156 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116157 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416158
[email protected]79e1fd62013-06-20 06:50:0416159 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616160 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416161 EXPECT_TRUE(request_headers.HasHeader("Host"));
16162}
16163
bncd16676a2016-07-20 16:23:0116164TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416165 HttpRequestInfo request;
16166 request.method = "GET";
bncce36dca22015-04-21 22:11:2316167 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016168 request.traffic_annotation =
16169 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416170
danakj1fd259a02016-04-16 03:17:0916171 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416173
16174 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316175 MockWrite(
16176 "GET / HTTP/1.1\r\n"
16177 "Host: www.example.org\r\n"
16178 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416179 };
16180 MockRead data_reads[] = {
16181 MockRead(ASYNC, ERR_CONNECTION_RESET),
16182 };
16183
16184 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16185 data_writes, arraysize(data_writes));
16186 session_deps_.socket_factory->AddSocketDataProvider(&data);
16187
16188 TestCompletionCallback callback;
16189
tfarina42834112016-09-22 13:38:2016190 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116191 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416192
16193 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116194 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416195
[email protected]79e1fd62013-06-20 06:50:0416196 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616197 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416198 EXPECT_TRUE(request_headers.HasHeader("Host"));
16199}
16200
bncd16676a2016-07-20 16:23:0116201TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416202 HttpRequestInfo request;
16203 request.method = "GET";
bncce36dca22015-04-21 22:11:2316204 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416205 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016206 request.traffic_annotation =
16207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416208
danakj1fd259a02016-04-16 03:17:0916209 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416211
16212 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316213 MockWrite(
16214 "GET / HTTP/1.1\r\n"
16215 "Host: www.example.org\r\n"
16216 "Connection: keep-alive\r\n"
16217 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416218 };
16219 MockRead data_reads[] = {
16220 MockRead("HTTP/1.1 200 OK\r\n"
16221 "Content-Length: 5\r\n\r\n"
16222 "hello"),
16223 MockRead(ASYNC, ERR_UNEXPECTED),
16224 };
16225
16226 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16227 data_writes, arraysize(data_writes));
16228 session_deps_.socket_factory->AddSocketDataProvider(&data);
16229
16230 TestCompletionCallback callback;
16231
tfarina42834112016-09-22 13:38:2016232 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416234
16235 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116236 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416237
16238 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616239 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416240 std::string foo;
16241 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16242 EXPECT_EQ("bar", foo);
16243}
16244
[email protected]bf828982013-08-14 18:01:4716245namespace {
16246
yhiranoa7e05bb2014-11-06 05:40:3916247// Fake HttpStream that simply records calls to SetPriority().
16248class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0316249 public base::SupportsWeakPtr<FakeStream> {
16250 public:
16251 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2716252 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0316253
16254 RequestPriority priority() const { return priority_; }
16255
dchengb03027d2014-10-21 12:00:2016256 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716257 bool can_send_early,
dchengb03027d2014-10-21 12:00:2016258 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016259 const NetLogWithSource& net_log,
Bence Békya25e3f72018-02-13 21:13:3916260 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316261 return ERR_IO_PENDING;
16262 }
16263
dchengb03027d2014-10-21 12:00:2016264 int SendRequest(const HttpRequestHeaders& request_headers,
16265 HttpResponseInfo* response,
Bence Békya25e3f72018-02-13 21:13:3916266 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316267 ADD_FAILURE();
16268 return ERR_UNEXPECTED;
16269 }
16270
Bence Békya25e3f72018-02-13 21:13:3916271 int ReadResponseHeaders(CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316272 ADD_FAILURE();
16273 return ERR_UNEXPECTED;
16274 }
16275
dchengb03027d2014-10-21 12:00:2016276 int ReadResponseBody(IOBuffer* buf,
16277 int buf_len,
Bence Békya25e3f72018-02-13 21:13:3916278 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316279 ADD_FAILURE();
16280 return ERR_UNEXPECTED;
16281 }
16282
dchengb03027d2014-10-21 12:00:2016283 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0316284
dchengb03027d2014-10-21 12:00:2016285 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0316286 ADD_FAILURE();
16287 return false;
16288 }
16289
dchengb03027d2014-10-21 12:00:2016290 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0316291 ADD_FAILURE();
16292 return false;
16293 }
16294
dchengb03027d2014-10-21 12:00:2016295 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316296
mmenkebd84c392015-09-02 14:12:3416297 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0316298
sclittle4de1bab92015-09-22 21:28:2416299 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5916300 ADD_FAILURE();
16301 return 0;
16302 }
16303
sclittlebe1ccf62015-09-02 19:40:3616304 int64_t GetTotalSentBytes() const override {
16305 ADD_FAILURE();
16306 return 0;
16307 }
16308
dchengb03027d2014-10-21 12:00:2016309 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0316310 ADD_FAILURE();
16311 return false;
16312 }
16313
rchcd379012017-04-12 21:53:3216314 bool GetAlternativeService(
16315 AlternativeService* alternative_service) const override {
16316 ADD_FAILURE();
16317 return false;
16318 }
16319
dchengb03027d2014-10-21 12:00:2016320 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
16321
16322 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0316323 ADD_FAILURE();
16324 }
16325
ttuttled9dbc652015-09-29 20:00:5916326 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16327
nharper78e6d2b2016-09-21 05:42:3516328 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16329 TokenBindingType tb_type,
16330 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416331 ADD_FAILURE();
16332 return ERR_NOT_IMPLEMENTED;
16333 }
16334
dchengb03027d2014-10-21 12:00:2016335 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316336
zhongyica364fbb2015-12-12 03:39:1216337 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16338
dchengb03027d2014-10-21 12:00:2016339 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0316340
yhiranoa7e05bb2014-11-06 05:40:3916341 HttpStream* RenewStreamForAuth() override { return NULL; }
16342
Andrey Kosyakov83a6eee2017-08-14 19:20:0416343 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
16344
[email protected]e86839fd2013-08-14 18:29:0316345 private:
16346 RequestPriority priority_;
16347
16348 DISALLOW_COPY_AND_ASSIGN(FakeStream);
16349};
16350
16351// Fake HttpStreamRequest that simply records calls to SetPriority()
16352// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4716353class FakeStreamRequest : public HttpStreamRequest,
16354 public base::SupportsWeakPtr<FakeStreamRequest> {
16355 public:
[email protected]e86839fd2013-08-14 18:29:0316356 FakeStreamRequest(RequestPriority priority,
16357 HttpStreamRequest::Delegate* delegate)
16358 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4416359 delegate_(delegate),
16360 websocket_stream_create_helper_(NULL) {}
16361
16362 FakeStreamRequest(RequestPriority priority,
16363 HttpStreamRequest::Delegate* delegate,
16364 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
16365 : priority_(priority),
16366 delegate_(delegate),
16367 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0316368
Chris Watkins7a41d3552017-12-01 02:13:2716369 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4716370
16371 RequestPriority priority() const { return priority_; }
16372
[email protected]831e4a32013-11-14 02:14:4416373 const WebSocketHandshakeStreamBase::CreateHelper*
16374 websocket_stream_create_helper() const {
16375 return websocket_stream_create_helper_;
16376 }
16377
[email protected]e86839fd2013-08-14 18:29:0316378 // Create a new FakeStream and pass it to the request's
16379 // delegate. Returns a weak pointer to the FakeStream.
16380 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1916381 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0316382 // Do this before calling OnStreamReady() as OnStreamReady() may
16383 // immediately delete |fake_stream|.
16384 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0016385 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0316386 return weak_stream;
16387 }
16388
asanka681f02d2017-02-22 17:06:3916389 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4716390 ADD_FAILURE();
16391 return ERR_UNEXPECTED;
16392 }
16393
dchengb03027d2014-10-21 12:00:2016394 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4716395 ADD_FAILURE();
16396 return LoadState();
16397 }
16398
dchengb03027d2014-10-21 12:00:2016399 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4716400
bnc94c92842016-09-21 15:22:5216401 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716402
bnc6227b26e2016-08-12 02:00:4316403 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4716404
dchengb03027d2014-10-21 12:00:2016405 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716406
ttuttle1f2d7e92015-04-28 16:17:4716407 const ConnectionAttempts& connection_attempts() const override {
16408 static ConnectionAttempts no_attempts;
16409 return no_attempts;
16410 }
16411
[email protected]bf828982013-08-14 18:01:4716412 private:
16413 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0316414 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4416415 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4716416
16417 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
16418};
16419
16420// Fake HttpStreamFactory that vends FakeStreamRequests.
16421class FakeStreamFactory : public HttpStreamFactory {
16422 public:
Chris Watkins7a41d3552017-12-01 02:13:2716423 FakeStreamFactory() = default;
16424 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4716425
16426 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
16427 // RequestStream() (which may be NULL if it was destroyed already).
16428 base::WeakPtr<FakeStreamRequest> last_stream_request() {
16429 return last_stream_request_;
16430 }
16431
xunjieli96f2a402017-06-05 17:24:2716432 std::unique_ptr<HttpStreamRequest> RequestStream(
16433 const HttpRequestInfo& info,
16434 RequestPriority priority,
16435 const SSLConfig& server_ssl_config,
16436 const SSLConfig& proxy_ssl_config,
16437 HttpStreamRequest::Delegate* delegate,
16438 bool enable_ip_based_pooling,
16439 bool enable_alternative_services,
16440 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1916441 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4716442 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716443 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716444 }
16445
xunjieli96f2a402017-06-05 17:24:2716446 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0816447 const HttpRequestInfo& info,
16448 RequestPriority priority,
16449 const SSLConfig& server_ssl_config,
16450 const SSLConfig& proxy_ssl_config,
16451 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2916452 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616453 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016454 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0816455 NOTREACHED();
16456 return nullptr;
16457 }
16458
xunjieli96f2a402017-06-05 17:24:2716459 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4716460 const HttpRequestInfo& info,
16461 RequestPriority priority,
16462 const SSLConfig& server_ssl_config,
16463 const SSLConfig& proxy_ssl_config,
16464 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4616465 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2916466 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616467 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016468 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2716469 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1916470 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4416471 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716472 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716473 }
16474
dchengb03027d2014-10-21 12:00:2016475 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5916476 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4716477 ADD_FAILURE();
16478 }
16479
dchengb03027d2014-10-21 12:00:2016480 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4716481 ADD_FAILURE();
16482 return NULL;
16483 }
16484
xunjielif5267de2017-01-20 21:18:5716485 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
16486 const std::string& parent_absolute_name) const override {
16487 ADD_FAILURE();
16488 }
16489
[email protected]bf828982013-08-14 18:01:4716490 private:
16491 base::WeakPtr<FakeStreamRequest> last_stream_request_;
16492
16493 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16494};
16495
[email protected]bf828982013-08-14 18:01:4716496} // namespace
16497
16498// Make sure that HttpNetworkTransaction passes on its priority to its
16499// stream request on start.
bncd16676a2016-07-20 16:23:0116500TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916501 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216502 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716503 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916504 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716505
krasinc06a72a2016-12-21 03:42:4616506 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116507 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716508
Ramin Halavatib5e433e62018-02-07 07:41:1016509 request.traffic_annotation =
16510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16511
wezca1070932016-05-26 20:30:5216512 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716513
[email protected]bf828982013-08-14 18:01:4716514 TestCompletionCallback callback;
16515 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016516 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716517
16518 base::WeakPtr<FakeStreamRequest> fake_request =
16519 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216520 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716521 EXPECT_EQ(LOW, fake_request->priority());
16522}
16523
16524// Make sure that HttpNetworkTransaction passes on its priority
16525// updates to its stream request.
bncd16676a2016-07-20 16:23:0116526TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916527 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216528 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716529 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916530 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716531
krasinc06a72a2016-12-21 03:42:4616532 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116533 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716534
Ramin Halavatib5e433e62018-02-07 07:41:1016535 request.traffic_annotation =
16536 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16537
[email protected]bf828982013-08-14 18:01:4716538 TestCompletionCallback callback;
16539 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016540 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716541
16542 base::WeakPtr<FakeStreamRequest> fake_request =
16543 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216544 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716545 EXPECT_EQ(LOW, fake_request->priority());
16546
16547 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216548 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716549 EXPECT_EQ(LOWEST, fake_request->priority());
16550}
16551
[email protected]e86839fd2013-08-14 18:29:0316552// Make sure that HttpNetworkTransaction passes on its priority
16553// updates to its stream.
bncd16676a2016-07-20 16:23:0116554TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216556 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316557 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916558 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316559
krasinc06a72a2016-12-21 03:42:4616560 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116561 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316562
Ramin Halavatib5e433e62018-02-07 07:41:1016563 request.traffic_annotation =
16564 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16565
[email protected]e86839fd2013-08-14 18:29:0316566 TestCompletionCallback callback;
16567 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016568 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316569
16570 base::WeakPtr<FakeStreamRequest> fake_request =
16571 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216572 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316573 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216574 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316575 EXPECT_EQ(LOW, fake_stream->priority());
16576
16577 trans.SetPriority(LOWEST);
16578 EXPECT_EQ(LOWEST, fake_stream->priority());
16579}
16580
[email protected]043b68c82013-08-22 23:41:5216581// Tests that when a used socket is returned to the SSL socket pool, it's closed
16582// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116583TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216584 ClientSocketPoolManager::set_max_sockets_per_group(
16585 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16586 ClientSocketPoolManager::set_max_sockets_per_pool(
16587 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16588
16589 // Set up SSL request.
16590
16591 HttpRequestInfo ssl_request;
16592 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316593 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016594 ssl_request.traffic_annotation =
16595 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216596
16597 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316598 MockWrite(
16599 "GET / HTTP/1.1\r\n"
16600 "Host: www.example.org\r\n"
16601 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216602 };
16603 MockRead ssl_reads[] = {
16604 MockRead("HTTP/1.1 200 OK\r\n"),
16605 MockRead("Content-Length: 11\r\n\r\n"),
16606 MockRead("hello world"),
16607 MockRead(SYNCHRONOUS, OK),
16608 };
16609 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16610 ssl_writes, arraysize(ssl_writes));
16611 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16612
16613 SSLSocketDataProvider ssl(ASYNC, OK);
16614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16615
16616 // Set up HTTP request.
16617
16618 HttpRequestInfo http_request;
16619 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316620 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016621 http_request.traffic_annotation =
16622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216623
16624 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316625 MockWrite(
16626 "GET / HTTP/1.1\r\n"
16627 "Host: www.example.org\r\n"
16628 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216629 };
16630 MockRead http_reads[] = {
16631 MockRead("HTTP/1.1 200 OK\r\n"),
16632 MockRead("Content-Length: 7\r\n\r\n"),
16633 MockRead("falafel"),
16634 MockRead(SYNCHRONOUS, OK),
16635 };
16636 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16637 http_writes, arraysize(http_writes));
16638 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16639
danakj1fd259a02016-04-16 03:17:0916640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216641
16642 // Start the SSL request.
16643 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616644 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016645 ASSERT_EQ(ERR_IO_PENDING,
16646 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16647 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216648
16649 // Start the HTTP request. Pool should stall.
16650 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616651 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016652 ASSERT_EQ(ERR_IO_PENDING,
16653 http_trans.Start(&http_request, http_callback.callback(),
16654 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116655 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216656
16657 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116658 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216659 std::string response_data;
bnc691fda62016-08-12 00:43:1616660 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216661 EXPECT_EQ("hello world", response_data);
16662
16663 // The SSL socket should automatically be closed, so the HTTP request can
16664 // start.
dcheng48459ac22014-08-26 00:46:4116665 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16666 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216667
16668 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116669 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616670 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216671 EXPECT_EQ("falafel", response_data);
16672
dcheng48459ac22014-08-26 00:46:4116673 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216674}
16675
16676// Tests that when a SSL connection is established but there's no corresponding
16677// request that needs it, the new socket is closed if the transport socket pool
16678// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116679TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216680 ClientSocketPoolManager::set_max_sockets_per_group(
16681 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16682 ClientSocketPoolManager::set_max_sockets_per_pool(
16683 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16684
16685 // Set up an ssl request.
16686
16687 HttpRequestInfo ssl_request;
16688 ssl_request.method = "GET";
16689 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1016690 ssl_request.traffic_annotation =
16691 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216692
16693 // No data will be sent on the SSL socket.
16694 StaticSocketDataProvider ssl_data;
16695 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16696
16697 SSLSocketDataProvider ssl(ASYNC, OK);
16698 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16699
16700 // Set up HTTP request.
16701
16702 HttpRequestInfo http_request;
16703 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316704 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016705 http_request.traffic_annotation =
16706 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216707
16708 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316709 MockWrite(
16710 "GET / HTTP/1.1\r\n"
16711 "Host: www.example.org\r\n"
16712 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216713 };
16714 MockRead http_reads[] = {
16715 MockRead("HTTP/1.1 200 OK\r\n"),
16716 MockRead("Content-Length: 7\r\n\r\n"),
16717 MockRead("falafel"),
16718 MockRead(SYNCHRONOUS, OK),
16719 };
16720 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16721 http_writes, arraysize(http_writes));
16722 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16723
danakj1fd259a02016-04-16 03:17:0916724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216725
16726 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16727 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916728 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916729 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116730 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216731
16732 // Start the HTTP request. Pool should stall.
16733 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616734 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016735 ASSERT_EQ(ERR_IO_PENDING,
16736 http_trans.Start(&http_request, http_callback.callback(),
16737 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116738 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216739
16740 // The SSL connection will automatically be closed once the connection is
16741 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116742 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216743 std::string response_data;
bnc691fda62016-08-12 00:43:1616744 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216745 EXPECT_EQ("falafel", response_data);
16746
dcheng48459ac22014-08-26 00:46:4116747 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216748}
16749
bncd16676a2016-07-20 16:23:0116750TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916751 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216752 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916753 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216754 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416755
16756 HttpRequestInfo request;
16757 request.method = "POST";
16758 request.url = GURL("http://www.foo.com/");
16759 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016760 request.traffic_annotation =
16761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416762
danakj1fd259a02016-04-16 03:17:0916763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416765 // Send headers successfully, but get an error while sending the body.
16766 MockWrite data_writes[] = {
16767 MockWrite("POST / HTTP/1.1\r\n"
16768 "Host: www.foo.com\r\n"
16769 "Connection: keep-alive\r\n"
16770 "Content-Length: 3\r\n\r\n"),
16771 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16772 };
16773
16774 MockRead data_reads[] = {
16775 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16776 MockRead("hello world"),
16777 MockRead(SYNCHRONOUS, OK),
16778 };
16779 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16780 arraysize(data_writes));
16781 session_deps_.socket_factory->AddSocketDataProvider(&data);
16782
16783 TestCompletionCallback callback;
16784
tfarina42834112016-09-22 13:38:2016785 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416787
16788 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116789 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416790
bnc691fda62016-08-12 00:43:1616791 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216792 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416793
wezca1070932016-05-26 20:30:5216794 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416795 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16796
16797 std::string response_data;
bnc691fda62016-08-12 00:43:1616798 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116799 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416800 EXPECT_EQ("hello world", response_data);
16801}
16802
16803// This test makes sure the retry logic doesn't trigger when reading an error
16804// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116805TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416806 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416808 MockWrite data_writes[] = {
16809 MockWrite("GET / HTTP/1.1\r\n"
16810 "Host: www.foo.com\r\n"
16811 "Connection: keep-alive\r\n\r\n"),
16812 MockWrite("POST / HTTP/1.1\r\n"
16813 "Host: www.foo.com\r\n"
16814 "Connection: keep-alive\r\n"
16815 "Content-Length: 3\r\n\r\n"),
16816 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16817 };
16818
16819 MockRead data_reads[] = {
16820 MockRead("HTTP/1.1 200 Peachy\r\n"
16821 "Content-Length: 14\r\n\r\n"),
16822 MockRead("first response"),
16823 MockRead("HTTP/1.1 400 Not OK\r\n"
16824 "Content-Length: 15\r\n\r\n"),
16825 MockRead("second response"),
16826 MockRead(SYNCHRONOUS, OK),
16827 };
16828 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16829 arraysize(data_writes));
16830 session_deps_.socket_factory->AddSocketDataProvider(&data);
16831
16832 TestCompletionCallback callback;
16833 HttpRequestInfo request1;
16834 request1.method = "GET";
16835 request1.url = GURL("http://www.foo.com/");
16836 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016837 request1.traffic_annotation =
16838 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416839
bnc87dcefc2017-05-25 12:47:5816840 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916841 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016842 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416844
16845 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116846 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416847
16848 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216849 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416850
wezca1070932016-05-26 20:30:5216851 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416852 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16853
16854 std::string response_data1;
16855 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116856 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416857 EXPECT_EQ("first response", response_data1);
16858 // Delete the transaction to release the socket back into the socket pool.
16859 trans1.reset();
16860
danakj1fd259a02016-04-16 03:17:0916861 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216862 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916863 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216864 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416865
16866 HttpRequestInfo request2;
16867 request2.method = "POST";
16868 request2.url = GURL("http://www.foo.com/");
16869 request2.upload_data_stream = &upload_data_stream;
16870 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016871 request2.traffic_annotation =
16872 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416873
bnc691fda62016-08-12 00:43:1616874 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016875 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416877
16878 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116879 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416880
bnc691fda62016-08-12 00:43:1616881 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216882 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416883
wezca1070932016-05-26 20:30:5216884 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416885 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16886
16887 std::string response_data2;
bnc691fda62016-08-12 00:43:1616888 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116889 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416890 EXPECT_EQ("second response", response_data2);
16891}
16892
bncd16676a2016-07-20 16:23:0116893TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416894 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916895 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216896 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916897 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216898 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416899
16900 HttpRequestInfo request;
16901 request.method = "POST";
16902 request.url = GURL("http://www.foo.com/");
16903 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016904 request.traffic_annotation =
16905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416906
danakj1fd259a02016-04-16 03:17:0916907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616908 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416909 // Send headers successfully, but get an error while sending the body.
16910 MockWrite data_writes[] = {
16911 MockWrite("POST / HTTP/1.1\r\n"
16912 "Host: www.foo.com\r\n"
16913 "Connection: keep-alive\r\n"
16914 "Content-Length: 3\r\n\r\n"
16915 "fo"),
16916 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16917 };
16918
16919 MockRead data_reads[] = {
16920 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16921 MockRead("hello world"),
16922 MockRead(SYNCHRONOUS, OK),
16923 };
16924 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16925 arraysize(data_writes));
16926 session_deps_.socket_factory->AddSocketDataProvider(&data);
16927
16928 TestCompletionCallback callback;
16929
tfarina42834112016-09-22 13:38:2016930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416932
16933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116934 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416935
bnc691fda62016-08-12 00:43:1616936 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216937 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416938
wezca1070932016-05-26 20:30:5216939 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416940 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16941
16942 std::string response_data;
bnc691fda62016-08-12 00:43:1616943 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116944 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416945 EXPECT_EQ("hello world", response_data);
16946}
16947
16948// This tests the more common case than the previous test, where headers and
16949// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116950TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716951 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416952
16953 HttpRequestInfo request;
16954 request.method = "POST";
16955 request.url = GURL("http://www.foo.com/");
16956 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016957 request.traffic_annotation =
16958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416959
danakj1fd259a02016-04-16 03:17:0916960 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616961 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416962 // Send headers successfully, but get an error while sending the body.
16963 MockWrite data_writes[] = {
16964 MockWrite("POST / HTTP/1.1\r\n"
16965 "Host: www.foo.com\r\n"
16966 "Connection: keep-alive\r\n"
16967 "Transfer-Encoding: chunked\r\n\r\n"),
16968 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16969 };
16970
16971 MockRead data_reads[] = {
16972 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16973 MockRead("hello world"),
16974 MockRead(SYNCHRONOUS, OK),
16975 };
16976 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16977 arraysize(data_writes));
16978 session_deps_.socket_factory->AddSocketDataProvider(&data);
16979
16980 TestCompletionCallback callback;
16981
tfarina42834112016-09-22 13:38:2016982 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416984 // Make sure the headers are sent before adding a chunk. This ensures that
16985 // they can't be merged with the body in a single send. Not currently
16986 // necessary since a chunked body is never merged with headers, but this makes
16987 // the test more future proof.
16988 base::RunLoop().RunUntilIdle();
16989
mmenkecbc2b712014-10-09 20:29:0716990 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416991
16992 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116993 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416994
bnc691fda62016-08-12 00:43:1616995 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216996 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416997
wezca1070932016-05-26 20:30:5216998 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416999 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17000
17001 std::string response_data;
bnc691fda62016-08-12 00:43:1617002 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117003 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417004 EXPECT_EQ("hello world", response_data);
17005}
17006
bncd16676a2016-07-20 16:23:0117007TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917008 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217009 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917010 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217011 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417012
17013 HttpRequestInfo request;
17014 request.method = "POST";
17015 request.url = GURL("http://www.foo.com/");
17016 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017017 request.traffic_annotation =
17018 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417019
danakj1fd259a02016-04-16 03:17:0917020 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417022
17023 MockWrite data_writes[] = {
17024 MockWrite("POST / HTTP/1.1\r\n"
17025 "Host: www.foo.com\r\n"
17026 "Connection: keep-alive\r\n"
17027 "Content-Length: 3\r\n\r\n"),
17028 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17029 };
17030
17031 MockRead data_reads[] = {
17032 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17033 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17034 MockRead("hello world"),
17035 MockRead(SYNCHRONOUS, OK),
17036 };
17037 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17038 arraysize(data_writes));
17039 session_deps_.socket_factory->AddSocketDataProvider(&data);
17040
17041 TestCompletionCallback callback;
17042
tfarina42834112016-09-22 13:38:2017043 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417045
17046 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117047 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417048
bnc691fda62016-08-12 00:43:1617049 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217050 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417051
wezca1070932016-05-26 20:30:5217052 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417053 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17054
17055 std::string response_data;
bnc691fda62016-08-12 00:43:1617056 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117057 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417058 EXPECT_EQ("hello world", response_data);
17059}
17060
bncd16676a2016-07-20 16:23:0117061TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
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/1.0 200 Just Dandy\r\n\r\n"),
17087 MockRead("hello world"),
17088 MockRead(SYNCHRONOUS, OK),
17089 };
17090 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17091 arraysize(data_writes));
17092 session_deps_.socket_factory->AddSocketDataProvider(&data);
17093
17094 TestCompletionCallback callback;
17095
tfarina42834112016-09-22 13:38:2017096 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417098
17099 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117100 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417101}
17102
bncd16676a2016-07-20 16:23:0117103TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417104 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917105 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217106 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917107 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217108 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417109
17110 HttpRequestInfo request;
17111 request.method = "POST";
17112 request.url = GURL("http://www.foo.com/");
17113 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017114 request.traffic_annotation =
17115 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417116
danakj1fd259a02016-04-16 03:17:0917117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417119 // Send headers successfully, but get an error while sending the body.
17120 MockWrite data_writes[] = {
17121 MockWrite("POST / HTTP/1.1\r\n"
17122 "Host: www.foo.com\r\n"
17123 "Connection: keep-alive\r\n"
17124 "Content-Length: 3\r\n\r\n"),
17125 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17126 };
17127
17128 MockRead data_reads[] = {
17129 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17130 MockRead("HTTP/1.0 302 Redirect\r\n"),
17131 MockRead("Location: http://somewhere-else.com/\r\n"),
17132 MockRead("Content-Length: 0\r\n\r\n"),
17133 MockRead(SYNCHRONOUS, OK),
17134 };
17135 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17136 arraysize(data_writes));
17137 session_deps_.socket_factory->AddSocketDataProvider(&data);
17138
17139 TestCompletionCallback callback;
17140
tfarina42834112016-09-22 13:38:2017141 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417143
17144 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117145 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417146}
17147
bncd16676a2016-07-20 16:23:0117148TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917149 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217150 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917151 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217152 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417153
17154 HttpRequestInfo request;
17155 request.method = "POST";
17156 request.url = GURL("http://www.foo.com/");
17157 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017158 request.traffic_annotation =
17159 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417160
danakj1fd259a02016-04-16 03:17:0917161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417163 // Send headers successfully, but get an error while sending the body.
17164 MockWrite data_writes[] = {
17165 MockWrite("POST / HTTP/1.1\r\n"
17166 "Host: www.foo.com\r\n"
17167 "Connection: keep-alive\r\n"
17168 "Content-Length: 3\r\n\r\n"),
17169 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17170 };
17171
17172 MockRead data_reads[] = {
17173 MockRead("HTTP 0.9 rocks!"),
17174 MockRead(SYNCHRONOUS, OK),
17175 };
17176 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17177 arraysize(data_writes));
17178 session_deps_.socket_factory->AddSocketDataProvider(&data);
17179
17180 TestCompletionCallback callback;
17181
tfarina42834112016-09-22 13:38:2017182 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417184
17185 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117186 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417187}
17188
bncd16676a2016-07-20 16:23:0117189TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917190 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217191 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917192 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217193 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417194
17195 HttpRequestInfo request;
17196 request.method = "POST";
17197 request.url = GURL("http://www.foo.com/");
17198 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017199 request.traffic_annotation =
17200 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417201
danakj1fd259a02016-04-16 03:17:0917202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417204 // Send headers successfully, but get an error while sending the body.
17205 MockWrite data_writes[] = {
17206 MockWrite("POST / HTTP/1.1\r\n"
17207 "Host: www.foo.com\r\n"
17208 "Connection: keep-alive\r\n"
17209 "Content-Length: 3\r\n\r\n"),
17210 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17211 };
17212
17213 MockRead data_reads[] = {
17214 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17215 MockRead(SYNCHRONOUS, OK),
17216 };
17217 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17218 arraysize(data_writes));
17219 session_deps_.socket_factory->AddSocketDataProvider(&data);
17220
17221 TestCompletionCallback callback;
17222
tfarina42834112016-09-22 13:38:2017223 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117224 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417225
17226 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117227 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417228}
17229
Bence Békydca6bd92018-01-30 13:43:0617230#if BUILDFLAG(ENABLE_WEBSOCKETS)
17231
17232namespace {
17233
17234void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17235 headers->SetHeader("Connection", "Upgrade");
17236 headers->SetHeader("Upgrade", "websocket");
17237 headers->SetHeader("Origin", "http://www.example.org");
17238 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617239}
17240
17241} // namespace
17242
17243TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Békydca6bd92018-01-30 13:43:0617244 std::string test_cases[] = {"ws://www.example.org/",
17245 "wss://www.example.org/"};
17246 for (size_t i = 0; i < arraysize(test_cases); ++i) {
17247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17248 HttpNetworkSessionPeer peer(session.get());
17249 FakeStreamFactory* fake_factory = new FakeStreamFactory();
17250 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
17251
17252 HttpRequestInfo request;
17253 request.method = "GET";
17254 request.url = GURL(test_cases[i]);
Ramin Halavatib5e433e62018-02-07 07:41:1017255 request.traffic_annotation =
17256 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617257
Bence Béky8d1c6052018-02-07 12:48:1517258 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17259
Bence Békydca6bd92018-01-30 13:43:0617260 HttpNetworkTransaction trans(LOW, session.get());
17261 trans.SetWebSocketHandshakeStreamCreateHelper(
17262 &websocket_stream_create_helper);
17263
17264 TestCompletionCallback callback;
17265 EXPECT_EQ(ERR_IO_PENDING,
17266 trans.Start(&request, callback.callback(), NetLogWithSource()));
17267
17268 base::WeakPtr<FakeStreamRequest> fake_request =
17269 fake_factory->last_stream_request();
17270 ASSERT_TRUE(fake_request);
17271 EXPECT_EQ(&websocket_stream_create_helper,
17272 fake_request->websocket_stream_create_helper());
17273 }
17274}
17275
Adam Rice425cf122015-01-19 06:18:2417276// Verify that proxy headers are not sent to the destination server when
17277// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117278TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417279 HttpRequestInfo request;
17280 request.method = "GET";
bncce36dca22015-04-21 22:11:2317281 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017282 request.traffic_annotation =
17283 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417284 AddWebSocketHeaders(&request.extra_headers);
17285
17286 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917287 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917288 ProxyResolutionService::CreateFixedFromPacResult(
17289 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417290
danakj1fd259a02016-04-16 03:17:0917291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417292
17293 // Since a proxy is configured, try to establish a tunnel.
17294 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717295 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17296 "Host: www.example.org:443\r\n"
17297 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417298
17299 // After calling trans->RestartWithAuth(), this is the request we should
17300 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717301 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17302 "Host: www.example.org:443\r\n"
17303 "Proxy-Connection: keep-alive\r\n"
17304 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417305
rsleevidb16bb02015-11-12 23:47:1717306 MockWrite("GET / HTTP/1.1\r\n"
17307 "Host: www.example.org\r\n"
17308 "Connection: Upgrade\r\n"
17309 "Upgrade: websocket\r\n"
17310 "Origin: http://www.example.org\r\n"
17311 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517312 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17313 "Sec-WebSocket-Extensions: permessage-deflate; "
17314 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417315
17316 // The proxy responds to the connect with a 407, using a persistent
17317 // connection.
17318 MockRead data_reads[] = {
17319 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517320 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17321 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17322 "Content-Length: 0\r\n"
17323 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417324
17325 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17326
Bence Béky8d1c6052018-02-07 12:48:1517327 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17328 "Upgrade: websocket\r\n"
17329 "Connection: Upgrade\r\n"
17330 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417331
17332 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17333 arraysize(data_writes));
17334 session_deps_.socket_factory->AddSocketDataProvider(&data);
17335 SSLSocketDataProvider ssl(ASYNC, OK);
17336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17337
Bence Béky8d1c6052018-02-07 12:48:1517338 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17339
bnc87dcefc2017-05-25 12:47:5817340 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917341 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417342 trans->SetWebSocketHandshakeStreamCreateHelper(
17343 &websocket_stream_create_helper);
17344
17345 {
17346 TestCompletionCallback callback;
17347
tfarina42834112016-09-22 13:38:2017348 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417350
17351 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117352 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417353 }
17354
17355 const HttpResponseInfo* response = trans->GetResponseInfo();
17356 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217357 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417358 EXPECT_EQ(407, response->headers->response_code());
17359
17360 {
17361 TestCompletionCallback callback;
17362
17363 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17364 callback.callback());
robpercival214763f2016-07-01 23:27:0117365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417366
17367 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117368 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417369 }
17370
17371 response = trans->GetResponseInfo();
17372 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217373 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417374
17375 EXPECT_EQ(101, response->headers->response_code());
17376
17377 trans.reset();
17378 session->CloseAllConnections();
17379}
17380
17381// Verify that proxy headers are not sent to the destination server when
17382// establishing a tunnel for an insecure WebSocket connection.
17383// This requires the authentication info to be injected into the auth cache
17384// due to crbug.com/395064
17385// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117386TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417387 HttpRequestInfo request;
17388 request.method = "GET";
bncce36dca22015-04-21 22:11:2317389 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017390 request.traffic_annotation =
17391 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417392 AddWebSocketHeaders(&request.extra_headers);
17393
17394 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917395 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917396 ProxyResolutionService::CreateFixedFromPacResult(
17397 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417398
danakj1fd259a02016-04-16 03:17:0917399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417400
17401 MockWrite data_writes[] = {
17402 // Try to establish a tunnel for the WebSocket connection, with
17403 // credentials. Because WebSockets have a separate set of socket pools,
17404 // they cannot and will not use the same TCP/IP connection as the
17405 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517406 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17407 "Host: www.example.org:80\r\n"
17408 "Proxy-Connection: keep-alive\r\n"
17409 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417410
Bence Béky8d1c6052018-02-07 12:48:1517411 MockWrite("GET / HTTP/1.1\r\n"
17412 "Host: www.example.org\r\n"
17413 "Connection: Upgrade\r\n"
17414 "Upgrade: websocket\r\n"
17415 "Origin: http://www.example.org\r\n"
17416 "Sec-WebSocket-Version: 13\r\n"
17417 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17418 "Sec-WebSocket-Extensions: permessage-deflate; "
17419 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417420
17421 MockRead data_reads[] = {
17422 // HTTP CONNECT with credentials.
17423 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17424
17425 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517426 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17427 "Upgrade: websocket\r\n"
17428 "Connection: Upgrade\r\n"
17429 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417430
17431 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17432 arraysize(data_writes));
17433 session_deps_.socket_factory->AddSocketDataProvider(&data);
17434
17435 session->http_auth_cache()->Add(
17436 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17437 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17438
Bence Béky8d1c6052018-02-07 12:48:1517439 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17440
bnc87dcefc2017-05-25 12:47:5817441 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917442 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417443 trans->SetWebSocketHandshakeStreamCreateHelper(
17444 &websocket_stream_create_helper);
17445
17446 TestCompletionCallback callback;
17447
tfarina42834112016-09-22 13:38:2017448 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417450
17451 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117452 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417453
17454 const HttpResponseInfo* response = trans->GetResponseInfo();
17455 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217456 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417457
17458 EXPECT_EQ(101, response->headers->response_code());
17459
17460 trans.reset();
17461 session->CloseAllConnections();
17462}
17463
Bence Békydca6bd92018-01-30 13:43:0617464#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17465
bncd16676a2016-07-20 16:23:0117466TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917467 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217468 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917469 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217470 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217471
17472 HttpRequestInfo request;
17473 request.method = "POST";
17474 request.url = GURL("http://www.foo.com/");
17475 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017476 request.traffic_annotation =
17477 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217478
danakj1fd259a02016-04-16 03:17:0917479 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217481 MockWrite data_writes[] = {
17482 MockWrite("POST / HTTP/1.1\r\n"
17483 "Host: www.foo.com\r\n"
17484 "Connection: keep-alive\r\n"
17485 "Content-Length: 3\r\n\r\n"),
17486 MockWrite("foo"),
17487 };
17488
17489 MockRead data_reads[] = {
17490 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17491 MockRead(SYNCHRONOUS, OK),
17492 };
17493 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17494 arraysize(data_writes));
17495 session_deps_.socket_factory->AddSocketDataProvider(&data);
17496
17497 TestCompletionCallback callback;
17498
17499 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017500 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117501 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217502
17503 std::string response_data;
bnc691fda62016-08-12 00:43:1617504 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217505
17506 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617507 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217508 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617509 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217510}
17511
bncd16676a2016-07-20 16:23:0117512TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917513 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217514 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917515 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217516 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217517
17518 HttpRequestInfo request;
17519 request.method = "POST";
17520 request.url = GURL("http://www.foo.com/");
17521 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017522 request.traffic_annotation =
17523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217524
danakj1fd259a02016-04-16 03:17:0917525 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217527 MockWrite data_writes[] = {
17528 MockWrite("POST / HTTP/1.1\r\n"
17529 "Host: www.foo.com\r\n"
17530 "Connection: keep-alive\r\n"
17531 "Content-Length: 3\r\n\r\n"),
17532 MockWrite("foo"),
17533 };
17534
17535 MockRead data_reads[] = {
17536 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17537 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17538 MockRead(SYNCHRONOUS, OK),
17539 };
17540 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17541 arraysize(data_writes));
17542 session_deps_.socket_factory->AddSocketDataProvider(&data);
17543
17544 TestCompletionCallback callback;
17545
17546 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017547 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117548 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217549
17550 std::string response_data;
bnc691fda62016-08-12 00:43:1617551 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217552
17553 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617554 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217555 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617556 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217557}
17558
bncd16676a2016-07-20 16:23:0117559TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217560 ChunkedUploadDataStream upload_data_stream(0);
17561
17562 HttpRequestInfo request;
17563 request.method = "POST";
17564 request.url = GURL("http://www.foo.com/");
17565 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017566 request.traffic_annotation =
17567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217568
danakj1fd259a02016-04-16 03:17:0917569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217571 // Send headers successfully, but get an error while sending the body.
17572 MockWrite data_writes[] = {
17573 MockWrite("POST / HTTP/1.1\r\n"
17574 "Host: www.foo.com\r\n"
17575 "Connection: keep-alive\r\n"
17576 "Transfer-Encoding: chunked\r\n\r\n"),
17577 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17578 };
17579
17580 MockRead data_reads[] = {
17581 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17582 MockRead(SYNCHRONOUS, OK),
17583 };
17584 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17585 arraysize(data_writes));
17586 session_deps_.socket_factory->AddSocketDataProvider(&data);
17587
17588 TestCompletionCallback callback;
17589
17590 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017591 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217592
17593 base::RunLoop().RunUntilIdle();
17594 upload_data_stream.AppendData("f", 1, false);
17595
17596 base::RunLoop().RunUntilIdle();
17597 upload_data_stream.AppendData("oo", 2, true);
17598
robpercival214763f2016-07-01 23:27:0117599 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217600
17601 std::string response_data;
bnc691fda62016-08-12 00:43:1617602 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217603
17604 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617605 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217606 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617607 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217608}
17609
rdsmith1d343be52016-10-21 20:37:5017610// Confirm that transactions whose throttle is created in (and stays in)
17611// the unthrottled state are not blocked.
17612TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17613 TestNetworkStreamThrottler* throttler(nullptr);
17614 std::unique_ptr<HttpNetworkSession> session(
17615 CreateSessionWithThrottler(&session_deps_, &throttler));
17616
17617 // Send a simple request and make sure it goes through.
17618 HttpRequestInfo request;
17619 request.method = "GET";
17620 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017621 request.traffic_annotation =
17622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017623
bnc87dcefc2017-05-25 12:47:5817624 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917625 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017626
17627 MockWrite data_writes[] = {
17628 MockWrite("GET / HTTP/1.1\r\n"
17629 "Host: www.example.org\r\n"
17630 "Connection: keep-alive\r\n\r\n"),
17631 };
17632 MockRead data_reads[] = {
17633 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17634 MockRead(SYNCHRONOUS, OK),
17635 };
17636 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17637 arraysize(data_writes));
17638 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17639
17640 TestCompletionCallback callback;
17641 trans->Start(&request, callback.callback(), NetLogWithSource());
17642 EXPECT_EQ(OK, callback.WaitForResult());
17643}
17644
17645// Confirm requests can be blocked by a throttler, and are resumed
17646// when the throttle is unblocked.
17647TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17648 TestNetworkStreamThrottler* throttler(nullptr);
17649 std::unique_ptr<HttpNetworkSession> session(
17650 CreateSessionWithThrottler(&session_deps_, &throttler));
17651
17652 // Send a simple request and make sure it goes through.
17653 HttpRequestInfo request;
17654 request.method = "GET";
17655 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017656 request.traffic_annotation =
17657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017658
17659 MockWrite data_writes[] = {
17660 MockWrite("GET / HTTP/1.1\r\n"
17661 "Host: www.example.org\r\n"
17662 "Connection: keep-alive\r\n\r\n"),
17663 };
17664 MockRead data_reads[] = {
17665 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17666 MockRead(SYNCHRONOUS, OK),
17667 };
17668 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17669 arraysize(data_writes));
17670 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17671
17672 // Start a request that will be throttled at start; confirm it
17673 // doesn't complete.
17674 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817675 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917676 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017677
17678 TestCompletionCallback callback;
17679 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17680 EXPECT_EQ(ERR_IO_PENDING, rv);
17681
17682 base::RunLoop().RunUntilIdle();
17683 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17684 EXPECT_FALSE(callback.have_result());
17685
17686 // Confirm the request goes on to complete when unthrottled.
17687 throttler->UnthrottleAllRequests();
17688 base::RunLoop().RunUntilIdle();
17689 ASSERT_TRUE(callback.have_result());
17690 EXPECT_EQ(OK, callback.WaitForResult());
17691}
17692
17693// Destroy a request while it's throttled.
17694TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17695 TestNetworkStreamThrottler* throttler(nullptr);
17696 std::unique_ptr<HttpNetworkSession> session(
17697 CreateSessionWithThrottler(&session_deps_, &throttler));
17698
17699 // Send a simple request and make sure it goes through.
17700 HttpRequestInfo request;
17701 request.method = "GET";
17702 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017703 request.traffic_annotation =
17704 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017705
17706 MockWrite data_writes[] = {
17707 MockWrite("GET / HTTP/1.1\r\n"
17708 "Host: www.example.org\r\n"
17709 "Connection: keep-alive\r\n\r\n"),
17710 };
17711 MockRead data_reads[] = {
17712 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17713 MockRead(SYNCHRONOUS, OK),
17714 };
17715 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17716 arraysize(data_writes));
17717 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17718
17719 // Start a request that will be throttled at start; confirm it
17720 // doesn't complete.
17721 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817722 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917723 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017724
17725 TestCompletionCallback callback;
17726 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17727 EXPECT_EQ(ERR_IO_PENDING, rv);
17728
17729 base::RunLoop().RunUntilIdle();
17730 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17731 EXPECT_FALSE(callback.have_result());
17732
17733 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17734 trans.reset();
17735 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17736}
17737
17738// Confirm the throttler receives SetPriority calls.
17739TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17740 TestNetworkStreamThrottler* throttler(nullptr);
17741 std::unique_ptr<HttpNetworkSession> session(
17742 CreateSessionWithThrottler(&session_deps_, &throttler));
17743
17744 // Send a simple request and make sure it goes through.
17745 HttpRequestInfo request;
17746 request.method = "GET";
17747 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017748 request.traffic_annotation =
17749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017750
17751 MockWrite data_writes[] = {
17752 MockWrite("GET / HTTP/1.1\r\n"
17753 "Host: www.example.org\r\n"
17754 "Connection: keep-alive\r\n\r\n"),
17755 };
17756 MockRead data_reads[] = {
17757 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17758 MockRead(SYNCHRONOUS, OK),
17759 };
17760 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17761 arraysize(data_writes));
17762 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17763
17764 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917765 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017766 // Start the transaction to associate a throttle with it.
17767 TestCompletionCallback callback;
17768 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17769 EXPECT_EQ(ERR_IO_PENDING, rv);
17770
17771 EXPECT_EQ(0, throttler->num_set_priority_calls());
17772 trans->SetPriority(LOW);
17773 EXPECT_EQ(1, throttler->num_set_priority_calls());
17774 EXPECT_EQ(LOW, throttler->last_priority_set());
17775
17776 throttler->UnthrottleAllRequests();
17777 base::RunLoop().RunUntilIdle();
17778 ASSERT_TRUE(callback.have_result());
17779 EXPECT_EQ(OK, callback.WaitForResult());
17780}
17781
17782// Confirm that unthrottling from a SetPriority call by the
17783// throttler works properly.
17784TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17785 TestNetworkStreamThrottler* throttler(nullptr);
17786 std::unique_ptr<HttpNetworkSession> session(
17787 CreateSessionWithThrottler(&session_deps_, &throttler));
17788
17789 // Send a simple request and make sure it goes through.
17790 HttpRequestInfo request;
17791 request.method = "GET";
17792 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017793 request.traffic_annotation =
17794 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017795
17796 MockWrite data_writes[] = {
17797 MockWrite("GET / HTTP/1.1\r\n"
17798 "Host: www.example.org\r\n"
17799 "Connection: keep-alive\r\n\r\n"),
17800 };
17801 MockRead data_reads[] = {
17802 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17803 MockRead(SYNCHRONOUS, OK),
17804 };
17805 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17806 arraysize(data_writes));
17807 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17808
17809 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17810 data_writes, arraysize(data_writes));
17811 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17812
17813 // Start a request that will be throttled at start; confirm it
17814 // doesn't complete.
17815 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817816 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917817 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017818
17819 TestCompletionCallback callback;
17820 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17821 EXPECT_EQ(ERR_IO_PENDING, rv);
17822
17823 base::RunLoop().RunUntilIdle();
17824 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17825 EXPECT_FALSE(callback.have_result());
17826
17827 // Create a new request, call SetPriority on it to unthrottle,
17828 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917829 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017830 throttler->set_priority_change_closure(
17831 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17832 base::Unretained(throttler)));
17833
17834 // Start the transaction to associate a throttle with it.
17835 TestCompletionCallback callback1;
17836 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17837 EXPECT_EQ(ERR_IO_PENDING, rv);
17838
17839 trans1->SetPriority(IDLE);
17840
17841 base::RunLoop().RunUntilIdle();
17842 ASSERT_TRUE(callback.have_result());
17843 EXPECT_EQ(OK, callback.WaitForResult());
17844 ASSERT_TRUE(callback1.have_result());
17845 EXPECT_EQ(OK, callback1.WaitForResult());
17846}
17847
17848// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817849void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017850
17851// Confirm that destroying a transaction from a SetPriority call by the
17852// throttler works properly.
17853TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17854 TestNetworkStreamThrottler* throttler(nullptr);
17855 std::unique_ptr<HttpNetworkSession> session(
17856 CreateSessionWithThrottler(&session_deps_, &throttler));
17857
17858 // Send a simple request and make sure it goes through.
17859 HttpRequestInfo request;
17860 request.method = "GET";
17861 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017862 request.traffic_annotation =
17863 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017864
17865 MockWrite data_writes[] = {
17866 MockWrite("GET / HTTP/1.1\r\n"
17867 "Host: www.example.org\r\n"
17868 "Connection: keep-alive\r\n\r\n"),
17869 };
17870 MockRead data_reads[] = {
17871 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17872 MockRead(SYNCHRONOUS, OK),
17873 };
17874 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17875 arraysize(data_writes));
17876 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17877
17878 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17879 data_writes, arraysize(data_writes));
17880 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17881
17882 // Start a request that will be throttled at start; confirm it
17883 // doesn't complete.
17884 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817885 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917886 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017887
17888 TestCompletionCallback callback;
17889 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17890 EXPECT_EQ(ERR_IO_PENDING, rv);
17891
17892 base::RunLoop().RunUntilIdle();
17893 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17894 EXPECT_FALSE(callback.have_result());
17895
17896 // Arrange for the set priority call on the above transaction to delete
17897 // the transaction.
bnc87dcefc2017-05-25 12:47:5817898 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017899 throttler->set_priority_change_closure(
17900 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17901
17902 // Call it and check results (partially a "doesn't crash" test).
17903 trans_ptr->SetPriority(IDLE);
17904 trans_ptr = nullptr; // No longer a valid pointer.
17905
17906 base::RunLoop().RunUntilIdle();
17907 ASSERT_FALSE(callback.have_result());
17908}
17909
nharperb7441ef2016-01-25 23:54:1417910#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117911TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417912 const std::string https_url = "https://www.example.com";
17913 HttpRequestInfo request;
17914 request.url = GURL(https_url);
17915 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:1017916 request.traffic_annotation =
17917 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417918
17919 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917920 ssl.ssl_info.token_binding_negotiated = true;
17921 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617922 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417923 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17924
bnc42331402016-07-25 13:36:1517925 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117926 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17927 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417928 MockRead(ASYNC, ERR_IO_PENDING)};
17929 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17930 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817931 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917932 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917933 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417934
17935 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17936 TestCompletionCallback callback;
17937 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017938 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017939
17940 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417941
17942 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17943 HttpRequestHeaders headers;
17944 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17945 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17946}
17947#endif // !defined(OS_IOS)
17948
eustasc7d27da2017-04-06 10:33:2017949void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17950 const std::string& accept_encoding,
17951 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317952 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017953 bool should_match) {
17954 HttpRequestInfo request;
17955 request.method = "GET";
17956 request.url = GURL("http://www.foo.com/");
17957 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17958 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1017959 request.traffic_annotation =
17960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017961
17962 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17964 // Send headers successfully, but get an error while sending the body.
17965 MockWrite data_writes[] = {
17966 MockWrite("GET / HTTP/1.1\r\n"
17967 "Host: www.foo.com\r\n"
17968 "Connection: keep-alive\r\n"
17969 "Accept-Encoding: "),
17970 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17971 };
17972
sky50576f32017-05-01 19:28:0317973 std::string response_code = "200 OK";
17974 std::string extra;
17975 if (!location.empty()) {
17976 response_code = "301 Redirect\r\nLocation: ";
17977 response_code.append(location);
17978 }
17979
eustasc7d27da2017-04-06 10:33:2017980 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317981 MockRead("HTTP/1.0 "),
17982 MockRead(response_code.data()),
17983 MockRead("\r\nContent-Encoding: "),
17984 MockRead(content_encoding.data()),
17985 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017986 MockRead(SYNCHRONOUS, OK),
17987 };
17988 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17989 arraysize(data_writes));
17990 session_deps->socket_factory->AddSocketDataProvider(&data);
17991
17992 TestCompletionCallback callback;
17993
17994 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17996
17997 rv = callback.WaitForResult();
17998 if (should_match) {
17999 EXPECT_THAT(rv, IsOk());
18000 } else {
18001 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18002 }
18003}
18004
18005TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318006 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018007}
18008
18009TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318010 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18011 true);
eustasc7d27da2017-04-06 10:33:2018012}
18013
18014TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18015 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318016 "", false);
18017}
18018
18019TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18020 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18021 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018022}
18023
xunjieli96f2a402017-06-05 17:24:2718024TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18025 ProxyConfig proxy_config;
18026 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18027 proxy_config.set_pac_mandatory(true);
18028 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918029 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918030 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18031 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418032 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718033
18034 HttpRequestInfo request;
18035 request.method = "GET";
18036 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018037 request.traffic_annotation =
18038 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718039
18040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18041 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18042
18043 TestCompletionCallback callback;
18044
18045 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18047 EXPECT_THAT(callback.WaitForResult(),
18048 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18049}
18050
18051TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18052 ProxyConfig proxy_config;
18053 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18054 proxy_config.set_pac_mandatory(true);
18055 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18056 new MockAsyncProxyResolverFactory(false);
18057 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918058 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918059 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18060 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918061 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718062 HttpRequestInfo request;
18063 request.method = "GET";
18064 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018065 request.traffic_annotation =
18066 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718067
18068 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18070
18071 TestCompletionCallback callback;
18072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18074
18075 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18076 ERR_FAILED, &resolver);
18077 EXPECT_THAT(callback.WaitForResult(),
18078 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18079}
18080
18081TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918082 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918083 ProxyResolutionService::CreateFixedFromPacResult(
18084 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718085 session_deps_.enable_quic = false;
18086 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18087
18088 HttpRequestInfo request;
18089 request.method = "GET";
18090 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018091 request.traffic_annotation =
18092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718093
18094 TestCompletionCallback callback;
18095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18096 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18098
18099 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18100}
18101
[email protected]89ceba9a2009-03-21 03:46:0618102} // namespace net