blob: e1bb8dcf7a0c7c17fbeebfcac7b403d9cad9f2b4 [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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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 Halavatib5e433e2018-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
bncd16676a2016-07-20 16:23:012693TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462694 HttpRequestInfo request;
2695 request.method = "GET";
bncce36dca22015-04-21 22:11:232696 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292697 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102698 request.traffic_annotation =
2699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462700
danakj1fd259a02016-04-16 03:17:092701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272703
[email protected]861fcd52009-08-26 02:33:462704 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232705 MockWrite(
2706 "GET / HTTP/1.1\r\n"
2707 "Host: www.example.org\r\n"
2708 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462709 };
2710
2711 MockRead data_reads[] = {
2712 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2713 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2714 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2715 // Large content-length -- won't matter, as connection will be reset.
2716 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062717 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462718 };
2719
[email protected]31a2bfe2010-02-09 08:03:392720 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2721 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072722 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412723 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462724
tfarina42834112016-09-22 13:38:202725 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462727
2728 rv = callback.WaitForResult();
2729 EXPECT_EQ(0, rv);
2730
sclittlefb249892015-09-10 21:33:222731 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162732 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222733 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162734 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192735
bnc691fda62016-08-12 00:43:162736 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522737 ASSERT_TRUE(response);
2738 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462739}
2740
[email protected]2d2697f92009-02-18 21:00:322741// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2742// connection.
bncd16676a2016-07-20 16:23:012743TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182744 // On the second pass, the body read of the auth challenge is synchronous, so
2745 // IsConnectedAndIdle returns false. The socket should still be drained and
2746 // reused. See http://crbug.com/544255.
2747 for (int i = 0; i < 2; ++i) {
2748 HttpRequestInfo request;
2749 request.method = "GET";
2750 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102751 request.traffic_annotation =
2752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322753
mmenkecc2298e2015-12-07 18:20:182754 TestNetLog log;
2755 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272757
mmenkecc2298e2015-12-07 18:20:182758 MockWrite data_writes[] = {
2759 MockWrite(ASYNC, 0,
2760 "GET / HTTP/1.1\r\n"
2761 "Host: www.example.org\r\n"
2762 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322763
bnc691fda62016-08-12 00:43:162764 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182765 // be issuing -- the final header line contains the credentials.
2766 MockWrite(ASYNC, 6,
2767 "GET / HTTP/1.1\r\n"
2768 "Host: www.example.org\r\n"
2769 "Connection: keep-alive\r\n"
2770 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2771 };
[email protected]2d2697f92009-02-18 21:00:322772
mmenkecc2298e2015-12-07 18:20:182773 MockRead data_reads[] = {
2774 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2775 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2776 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2777 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2778 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322779
mmenkecc2298e2015-12-07 18:20:182780 // Lastly, the server responds with the actual content.
2781 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2782 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2783 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2784 MockRead(ASYNC, 10, "Hello"),
2785 };
[email protected]2d2697f92009-02-18 21:00:322786
mmenkecc2298e2015-12-07 18:20:182787 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2788 arraysize(data_writes));
2789 data.set_busy_before_sync_reads(true);
2790 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462791
mmenkecc2298e2015-12-07 18:20:182792 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322793
bnc691fda62016-08-12 00:43:162794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202795 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012796 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322797
mmenkecc2298e2015-12-07 18:20:182798 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162799 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182800 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322801
bnc691fda62016-08-12 00:43:162802 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182803 ASSERT_TRUE(response);
2804 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322805
mmenkecc2298e2015-12-07 18:20:182806 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252807
bnc691fda62016-08-12 00:43:162808 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2809 callback2.callback());
robpercival214763f2016-07-01 23:27:012810 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322811
mmenkecc2298e2015-12-07 18:20:182812 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162813 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182814 TestLoadTimingReused(load_timing_info2);
2815 // The load timing after restart should have the same socket ID, and times
2816 // those of the first load timing.
2817 EXPECT_LE(load_timing_info1.receive_headers_end,
2818 load_timing_info2.send_start);
2819 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322820
bnc691fda62016-08-12 00:43:162821 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182822 ASSERT_TRUE(response);
2823 EXPECT_FALSE(response->auth_challenge);
2824 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322825
mmenkecc2298e2015-12-07 18:20:182826 std::string response_data;
bnc691fda62016-08-12 00:43:162827 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322828
mmenkecc2298e2015-12-07 18:20:182829 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162830 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182831 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162832 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182833 }
[email protected]2d2697f92009-02-18 21:00:322834}
2835
2836// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2837// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012838TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422839 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322840 request.method = "GET";
bncce36dca22015-04-21 22:11:232841 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102842 request.traffic_annotation =
2843 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322844
danakj1fd259a02016-04-16 03:17:092845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272846
[email protected]2d2697f92009-02-18 21:00:322847 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162848 MockWrite("GET / HTTP/1.1\r\n"
2849 "Host: www.example.org\r\n"
2850 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322851
bnc691fda62016-08-12 00:43:162852 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232853 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162854 MockWrite("GET / HTTP/1.1\r\n"
2855 "Host: www.example.org\r\n"
2856 "Connection: keep-alive\r\n"
2857 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322858 };
2859
[email protected]2d2697f92009-02-18 21:00:322860 MockRead data_reads1[] = {
2861 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2862 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312863 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322864
2865 // Lastly, the server responds with the actual content.
2866 MockRead("HTTP/1.1 200 OK\r\n"),
2867 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502868 MockRead("Content-Length: 5\r\n\r\n"),
2869 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322870 };
2871
[email protected]2d0a4f92011-05-05 16:38:462872 // An incorrect reconnect would cause this to be read.
2873 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062874 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462875 };
2876
[email protected]31a2bfe2010-02-09 08:03:392877 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2878 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462879 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2880 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072881 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2882 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322883
[email protected]49639fa2011-12-20 23:22:412884 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322885
bnc691fda62016-08-12 00:43:162886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202887 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322889
2890 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012891 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322892
bnc691fda62016-08-12 00:43:162893 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522894 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042895 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322896
[email protected]49639fa2011-12-20 23:22:412897 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322898
bnc691fda62016-08-12 00:43:162899 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322901
2902 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012903 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322904
bnc691fda62016-08-12 00:43:162905 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522906 ASSERT_TRUE(response);
2907 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502908 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322909}
2910
2911// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2912// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012913TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422914 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322915 request.method = "GET";
bncce36dca22015-04-21 22:11:232916 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102917 request.traffic_annotation =
2918 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322919
danakj1fd259a02016-04-16 03:17:092920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272921
[email protected]2d2697f92009-02-18 21:00:322922 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162923 MockWrite("GET / HTTP/1.1\r\n"
2924 "Host: www.example.org\r\n"
2925 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322926
bnc691fda62016-08-12 00:43:162927 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232928 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162929 MockWrite("GET / HTTP/1.1\r\n"
2930 "Host: www.example.org\r\n"
2931 "Connection: keep-alive\r\n"
2932 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322933 };
2934
2935 // Respond with 5 kb of response body.
2936 std::string large_body_string("Unauthorized");
2937 large_body_string.append(5 * 1024, ' ');
2938 large_body_string.append("\r\n");
2939
2940 MockRead data_reads1[] = {
2941 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2942 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2943 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2944 // 5134 = 12 + 5 * 1024 + 2
2945 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062946 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322947
2948 // Lastly, the server responds with the actual content.
2949 MockRead("HTTP/1.1 200 OK\r\n"),
2950 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502951 MockRead("Content-Length: 5\r\n\r\n"),
2952 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322953 };
2954
[email protected]2d0a4f92011-05-05 16:38:462955 // An incorrect reconnect would cause this to be read.
2956 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062957 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462958 };
2959
[email protected]31a2bfe2010-02-09 08:03:392960 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2961 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462962 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2963 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2965 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322966
[email protected]49639fa2011-12-20 23:22:412967 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322968
bnc691fda62016-08-12 00:43:162969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202970 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322972
2973 rv = callback1.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 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522977 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042978 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322979
[email protected]49639fa2011-12-20 23:22:412980 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322981
bnc691fda62016-08-12 00:43:162982 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322984
2985 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012986 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322987
bnc691fda62016-08-12 00:43:162988 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522989 ASSERT_TRUE(response);
2990 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502991 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322992}
2993
2994// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312995// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012996TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312997 HttpRequestInfo request;
2998 request.method = "GET";
bncce36dca22015-04-21 22:11:232999 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103000 request.traffic_annotation =
3001 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313002
danakj1fd259a02016-04-16 03:17:093003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273004
[email protected]11203f012009-11-12 23:02:313005 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233006 MockWrite(
3007 "GET / HTTP/1.1\r\n"
3008 "Host: www.example.org\r\n"
3009 "Connection: keep-alive\r\n\r\n"),
3010 // This simulates the seemingly successful write to a closed connection
3011 // if the bug is not fixed.
3012 MockWrite(
3013 "GET / HTTP/1.1\r\n"
3014 "Host: www.example.org\r\n"
3015 "Connection: keep-alive\r\n"
3016 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313017 };
3018
3019 MockRead data_reads1[] = {
3020 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3021 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3022 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3023 MockRead("Content-Length: 14\r\n\r\n"),
3024 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063025 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313026 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063027 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313028 };
3029
bnc691fda62016-08-12 00:43:163030 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313031 // be issuing -- the final header line contains the credentials.
3032 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233033 MockWrite(
3034 "GET / HTTP/1.1\r\n"
3035 "Host: www.example.org\r\n"
3036 "Connection: keep-alive\r\n"
3037 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313038 };
3039
3040 // Lastly, the server responds with the actual content.
3041 MockRead data_reads2[] = {
3042 MockRead("HTTP/1.1 200 OK\r\n"),
3043 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503044 MockRead("Content-Length: 5\r\n\r\n"),
3045 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313046 };
3047
[email protected]31a2bfe2010-02-09 08:03:393048 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3049 data_writes1, arraysize(data_writes1));
3050 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3051 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073052 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3053 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313054
[email protected]49639fa2011-12-20 23:22:413055 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313056
bnc691fda62016-08-12 00:43:163057 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203058 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313060
3061 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013062 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313063
bnc691fda62016-08-12 00:43:163064 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523065 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043066 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313067
[email protected]49639fa2011-12-20 23:22:413068 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313069
bnc691fda62016-08-12 00:43:163070 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313072
3073 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013074 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313075
bnc691fda62016-08-12 00:43:163076 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523077 ASSERT_TRUE(response);
3078 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503079 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313080}
3081
[email protected]394816e92010-08-03 07:38:593082// Test the request-challenge-retry sequence for basic auth, over a connection
3083// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013084TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013085 HttpRequestInfo request;
3086 request.method = "GET";
bncce36dca22015-04-21 22:11:233087 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013088 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293089 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103090 request.traffic_annotation =
3091 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013092
3093 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593094 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493095 ProxyResolutionService::CreateFixedFromPacResult(
3096 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513097 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013098 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013100
3101 // Since we have proxy, should try to establish tunnel.
3102 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543103 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173104 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543105 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013106 };
3107
mmenkee71e15332015-10-07 16:39:543108 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013109 // connection.
3110 MockRead data_reads1[] = {
3111 // No credentials.
3112 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3113 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543114 };
ttuttle34f63b52015-03-05 04:33:013115
mmenkee71e15332015-10-07 16:39:543116 // Since the first connection couldn't be reused, need to establish another
3117 // once given credentials.
3118 MockWrite data_writes2[] = {
3119 // After calling trans->RestartWithAuth(), this is the request we should
3120 // be issuing -- the final header line contains the credentials.
3121 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173122 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543123 "Proxy-Connection: keep-alive\r\n"
3124 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3125
3126 MockWrite("GET / HTTP/1.1\r\n"
3127 "Host: www.example.org\r\n"
3128 "Connection: keep-alive\r\n\r\n"),
3129 };
3130
3131 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013132 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3133
3134 MockRead("HTTP/1.1 200 OK\r\n"),
3135 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3136 MockRead("Content-Length: 5\r\n\r\n"),
3137 MockRead(SYNCHRONOUS, "hello"),
3138 };
3139
3140 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3141 data_writes1, arraysize(data_writes1));
3142 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543143 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3144 data_writes2, arraysize(data_writes2));
3145 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013146 SSLSocketDataProvider ssl(ASYNC, OK);
3147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3148
3149 TestCompletionCallback callback1;
3150
bnc87dcefc2017-05-25 12:47:583151 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193152 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013153
3154 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013156
3157 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013158 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463159 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013160 log.GetEntries(&entries);
3161 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003162 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3163 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013164 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003165 entries, pos,
3166 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3167 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013168
3169 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523170 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013171 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523172 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013173 EXPECT_EQ(407, response->headers->response_code());
3174 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3175 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3176
3177 LoadTimingInfo load_timing_info;
3178 // CONNECT requests and responses are handled at the connect job level, so
3179 // the transaction does not yet have a connection.
3180 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3181
3182 TestCompletionCallback callback2;
3183
3184 rv =
3185 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013187
3188 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013189 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013190
3191 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523192 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013193
3194 EXPECT_TRUE(response->headers->IsKeepAlive());
3195 EXPECT_EQ(200, response->headers->response_code());
3196 EXPECT_EQ(5, response->headers->GetContentLength());
3197 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3198
3199 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523200 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013201
3202 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3203 TestLoadTimingNotReusedWithPac(load_timing_info,
3204 CONNECT_TIMING_HAS_SSL_TIMES);
3205
3206 trans.reset();
3207 session->CloseAllConnections();
3208}
3209
3210// Test the request-challenge-retry sequence for basic auth, over a connection
3211// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013212TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593213 HttpRequestInfo request;
3214 request.method = "GET";
bncce36dca22015-04-21 22:11:233215 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593216 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293217 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103218 request.traffic_annotation =
3219 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593220
[email protected]cb9bf6ca2011-01-28 13:15:273221 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593222 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493223 ProxyResolutionService::CreateFixedFromPacResult(
3224 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513225 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073226 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273228
[email protected]394816e92010-08-03 07:38:593229 // Since we have proxy, should try to establish tunnel.
3230 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543231 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173232 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543233 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113234 };
3235
mmenkee71e15332015-10-07 16:39:543236 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083237 // connection.
3238 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543239 // No credentials.
3240 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3241 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3242 MockRead("Proxy-Connection: close\r\n\r\n"),
3243 };
mmenkee0b5c882015-08-26 20:29:113244
mmenkee71e15332015-10-07 16:39:543245 MockWrite data_writes2[] = {
3246 // After calling trans->RestartWithAuth(), this is the request we should
3247 // be issuing -- the final header line contains the credentials.
3248 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173249 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543250 "Proxy-Connection: keep-alive\r\n"
3251 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083252
mmenkee71e15332015-10-07 16:39:543253 MockWrite("GET / HTTP/1.1\r\n"
3254 "Host: www.example.org\r\n"
3255 "Connection: keep-alive\r\n\r\n"),
3256 };
3257
3258 MockRead data_reads2[] = {
3259 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3260
3261 MockRead("HTTP/1.1 200 OK\r\n"),
3262 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3263 MockRead("Content-Length: 5\r\n\r\n"),
3264 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593265 };
3266
3267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3268 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543270 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3271 data_writes2, arraysize(data_writes2));
3272 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063273 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593275
[email protected]49639fa2011-12-20 23:22:413276 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593277
bnc87dcefc2017-05-25 12:47:583278 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193279 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503280
[email protected]49639fa2011-12-20 23:22:413281 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593283
3284 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013285 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463286 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403287 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593288 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003289 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3290 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593291 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403292 entries, pos,
mikecirone8b85c432016-09-08 19:11:003293 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3294 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593295
3296 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523297 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013298 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523299 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593300 EXPECT_EQ(407, response->headers->response_code());
3301 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043302 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593303
[email protected]029c83b62013-01-24 05:28:203304 LoadTimingInfo load_timing_info;
3305 // CONNECT requests and responses are handled at the connect job level, so
3306 // the transaction does not yet have a connection.
3307 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3308
[email protected]49639fa2011-12-20 23:22:413309 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593310
[email protected]49639fa2011-12-20 23:22:413311 rv = trans->RestartWithAuth(
3312 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013313 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593314
3315 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013316 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593317
3318 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523319 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593320
3321 EXPECT_TRUE(response->headers->IsKeepAlive());
3322 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503323 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593324 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3325
3326 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523327 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503328
[email protected]029c83b62013-01-24 05:28:203329 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3330 TestLoadTimingNotReusedWithPac(load_timing_info,
3331 CONNECT_TIMING_HAS_SSL_TIMES);
3332
[email protected]0b0bf032010-09-21 18:08:503333 trans.reset();
[email protected]102e27c2011-02-23 01:01:313334 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593335}
3336
[email protected]11203f012009-11-12 23:02:313337// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013338// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013339TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233340 // On the second pass, the body read of the auth challenge is synchronous, so
3341 // IsConnectedAndIdle returns false. The socket should still be drained and
3342 // reused. See http://crbug.com/544255.
3343 for (int i = 0; i < 2; ++i) {
3344 HttpRequestInfo request;
3345 request.method = "GET";
3346 request.url = GURL("https://www.example.org/");
3347 // Ensure that proxy authentication is attempted even
3348 // when the no authentication data flag is set.
3349 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103350 request.traffic_annotation =
3351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013352
mmenked39192ee2015-12-09 00:57:233353 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593354 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493355 ProxyResolutionService::CreateFixed("myproxy:70",
3356 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233357 BoundTestNetLog log;
3358 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013360
bnc691fda62016-08-12 00:43:163361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013362
mmenked39192ee2015-12-09 00:57:233363 // Since we have proxy, should try to establish tunnel.
3364 MockWrite data_writes1[] = {
3365 MockWrite(ASYNC, 0,
3366 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3367 "Host: www.example.org:443\r\n"
3368 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013369
bnc691fda62016-08-12 00:43:163370 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233371 // be issuing -- the final header line contains the credentials.
3372 MockWrite(ASYNC, 3,
3373 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3374 "Host: www.example.org:443\r\n"
3375 "Proxy-Connection: keep-alive\r\n"
3376 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3377 };
ttuttle34f63b52015-03-05 04:33:013378
mmenked39192ee2015-12-09 00:57:233379 // The proxy responds to the connect with a 407, using a persistent
3380 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3381 MockRead data_reads1[] = {
3382 // No credentials.
3383 MockRead(ASYNC, 1,
3384 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3385 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3386 "Proxy-Connection: keep-alive\r\n"
3387 "Content-Length: 10\r\n\r\n"),
3388 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013389
mmenked39192ee2015-12-09 00:57:233390 // Wrong credentials (wrong password).
3391 MockRead(ASYNC, 4,
3392 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3393 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3394 "Proxy-Connection: keep-alive\r\n"
3395 "Content-Length: 10\r\n\r\n"),
3396 // No response body because the test stops reading here.
3397 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3398 };
ttuttle34f63b52015-03-05 04:33:013399
mmenked39192ee2015-12-09 00:57:233400 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3401 arraysize(data_writes1));
3402 data1.set_busy_before_sync_reads(true);
3403 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013404
mmenked39192ee2015-12-09 00:57:233405 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013406
bnc691fda62016-08-12 00:43:163407 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013408 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013409
mmenked39192ee2015-12-09 00:57:233410 TestNetLogEntry::List entries;
3411 log.GetEntries(&entries);
3412 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003413 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3414 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233415 ExpectLogContainsSomewhere(
3416 entries, pos,
mikecirone8b85c432016-09-08 19:11:003417 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3418 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013419
bnc691fda62016-08-12 00:43:163420 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233421 ASSERT_TRUE(response);
3422 ASSERT_TRUE(response->headers);
3423 EXPECT_TRUE(response->headers->IsKeepAlive());
3424 EXPECT_EQ(407, response->headers->response_code());
3425 EXPECT_EQ(10, response->headers->GetContentLength());
3426 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3427 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013428
mmenked39192ee2015-12-09 00:57:233429 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013430
mmenked39192ee2015-12-09 00:57:233431 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163432 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3433 callback2.callback());
robpercival214763f2016-07-01 23:27:013434 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013435
bnc691fda62016-08-12 00:43:163436 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233437 ASSERT_TRUE(response);
3438 ASSERT_TRUE(response->headers);
3439 EXPECT_TRUE(response->headers->IsKeepAlive());
3440 EXPECT_EQ(407, response->headers->response_code());
3441 EXPECT_EQ(10, response->headers->GetContentLength());
3442 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3443 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013444
mmenked39192ee2015-12-09 00:57:233445 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3446 // out of scope.
3447 session->CloseAllConnections();
3448 }
ttuttle34f63b52015-03-05 04:33:013449}
3450
3451// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3452// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013453TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233454 // On the second pass, the body read of the auth challenge is synchronous, so
3455 // IsConnectedAndIdle returns false. The socket should still be drained and
3456 // reused. See http://crbug.com/544255.
3457 for (int i = 0; i < 2; ++i) {
3458 HttpRequestInfo request;
3459 request.method = "GET";
3460 request.url = GURL("https://www.example.org/");
3461 // Ensure that proxy authentication is attempted even
3462 // when the no authentication data flag is set.
3463 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103464 request.traffic_annotation =
3465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233466
3467 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593468 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493469 ProxyResolutionService::CreateFixed("myproxy:70",
3470 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233471 BoundTestNetLog log;
3472 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233474
bnc691fda62016-08-12 00:43:163475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233476
3477 // Since we have proxy, should try to establish tunnel.
3478 MockWrite data_writes1[] = {
3479 MockWrite(ASYNC, 0,
3480 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3481 "Host: www.example.org:443\r\n"
3482 "Proxy-Connection: keep-alive\r\n\r\n"),
3483
bnc691fda62016-08-12 00:43:163484 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233485 // be issuing -- the final header line contains the credentials.
3486 MockWrite(ASYNC, 3,
3487 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3488 "Host: www.example.org:443\r\n"
3489 "Proxy-Connection: keep-alive\r\n"
3490 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3491 };
3492
3493 // The proxy responds to the connect with a 407, using a persistent
3494 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3495 MockRead data_reads1[] = {
3496 // No credentials.
3497 MockRead(ASYNC, 1,
3498 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3499 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3500 "Content-Length: 10\r\n\r\n"),
3501 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3502
3503 // Wrong credentials (wrong password).
3504 MockRead(ASYNC, 4,
3505 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3506 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3507 "Content-Length: 10\r\n\r\n"),
3508 // No response body because the test stops reading here.
3509 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3510 };
3511
3512 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3513 arraysize(data_writes1));
3514 data1.set_busy_before_sync_reads(true);
3515 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3516
3517 TestCompletionCallback callback1;
3518
bnc691fda62016-08-12 00:43:163519 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013520 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233521
3522 TestNetLogEntry::List entries;
3523 log.GetEntries(&entries);
3524 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003525 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3526 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233527 ExpectLogContainsSomewhere(
3528 entries, pos,
mikecirone8b85c432016-09-08 19:11:003529 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3530 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233531
bnc691fda62016-08-12 00:43:163532 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233533 ASSERT_TRUE(response);
3534 ASSERT_TRUE(response->headers);
3535 EXPECT_TRUE(response->headers->IsKeepAlive());
3536 EXPECT_EQ(407, response->headers->response_code());
3537 EXPECT_EQ(10, response->headers->GetContentLength());
3538 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3539 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3540
3541 TestCompletionCallback callback2;
3542
3543 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163544 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3545 callback2.callback());
robpercival214763f2016-07-01 23:27:013546 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233547
bnc691fda62016-08-12 00:43:163548 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233549 ASSERT_TRUE(response);
3550 ASSERT_TRUE(response->headers);
3551 EXPECT_TRUE(response->headers->IsKeepAlive());
3552 EXPECT_EQ(407, response->headers->response_code());
3553 EXPECT_EQ(10, response->headers->GetContentLength());
3554 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3555 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3556
3557 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3558 // out of scope.
3559 session->CloseAllConnections();
3560 }
3561}
3562
3563// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3564// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3565// the case the server sends extra data on the original socket, so it can't be
3566// reused.
bncd16676a2016-07-20 16:23:013567TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273568 HttpRequestInfo request;
3569 request.method = "GET";
bncce36dca22015-04-21 22:11:233570 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273571 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293572 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103573 request.traffic_annotation =
3574 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273575
[email protected]2d2697f92009-02-18 21:00:323576 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593577 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493578 ProxyResolutionService::CreateFixedFromPacResult(
3579 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513580 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073581 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323583
[email protected]2d2697f92009-02-18 21:00:323584 // Since we have proxy, should try to establish tunnel.
3585 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233586 MockWrite(ASYNC, 0,
3587 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173588 "Host: www.example.org:443\r\n"
3589 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233590 };
[email protected]2d2697f92009-02-18 21:00:323591
mmenked39192ee2015-12-09 00:57:233592 // The proxy responds to the connect with a 407, using a persistent, but sends
3593 // extra data, so the socket cannot be reused.
3594 MockRead data_reads1[] = {
3595 // No credentials.
3596 MockRead(ASYNC, 1,
3597 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3598 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3599 "Content-Length: 10\r\n\r\n"),
3600 MockRead(SYNCHRONOUS, 2, "0123456789"),
3601 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3602 };
3603
3604 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233605 // After calling trans->RestartWithAuth(), this is the request we should
3606 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233607 MockWrite(ASYNC, 0,
3608 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173609 "Host: www.example.org:443\r\n"
3610 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233611 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3612
3613 MockWrite(ASYNC, 2,
3614 "GET / HTTP/1.1\r\n"
3615 "Host: www.example.org\r\n"
3616 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323617 };
3618
mmenked39192ee2015-12-09 00:57:233619 MockRead data_reads2[] = {
3620 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323621
mmenked39192ee2015-12-09 00:57:233622 MockRead(ASYNC, 3,
3623 "HTTP/1.1 200 OK\r\n"
3624 "Content-Type: text/html; charset=iso-8859-1\r\n"
3625 "Content-Length: 5\r\n\r\n"),
3626 // No response body because the test stops reading here.
3627 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323628 };
3629
mmenked39192ee2015-12-09 00:57:233630 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3631 arraysize(data_writes1));
3632 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073633 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233634 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3635 arraysize(data_writes2));
3636 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3637 SSLSocketDataProvider ssl(ASYNC, OK);
3638 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323639
[email protected]49639fa2011-12-20 23:22:413640 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323641
bnc87dcefc2017-05-25 12:47:583642 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193643 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323644
mmenked39192ee2015-12-09 00:57:233645 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013646 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233647
mmenke43758e62015-05-04 21:09:463648 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403649 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393650 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003651 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3652 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393653 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403654 entries, pos,
mikecirone8b85c432016-09-08 19:11:003655 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3656 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323657
[email protected]1c773ea12009-04-28 19:58:423658 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243659 ASSERT_TRUE(response);
3660 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323661 EXPECT_TRUE(response->headers->IsKeepAlive());
3662 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423663 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043664 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323665
mmenked39192ee2015-12-09 00:57:233666 LoadTimingInfo load_timing_info;
3667 // CONNECT requests and responses are handled at the connect job level, so
3668 // the transaction does not yet have a connection.
3669 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3670
[email protected]49639fa2011-12-20 23:22:413671 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323672
mmenked39192ee2015-12-09 00:57:233673 rv =
3674 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013675 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323676
[email protected]2d2697f92009-02-18 21:00:323677 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233678 EXPECT_EQ(200, response->headers->response_code());
3679 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423680 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133681
mmenked39192ee2015-12-09 00:57:233682 // The password prompt info should not be set.
3683 EXPECT_FALSE(response->auth_challenge);
3684
3685 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3686 TestLoadTimingNotReusedWithPac(load_timing_info,
3687 CONNECT_TIMING_HAS_SSL_TIMES);
3688
3689 trans.reset();
[email protected]102e27c2011-02-23 01:01:313690 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323691}
3692
mmenkee71e15332015-10-07 16:39:543693// Test the case a proxy closes a socket while the challenge body is being
3694// drained.
bncd16676a2016-07-20 16:23:013695TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543696 HttpRequestInfo request;
3697 request.method = "GET";
3698 request.url = GURL("https://www.example.org/");
3699 // Ensure that proxy authentication is attempted even
3700 // when the no authentication data flag is set.
3701 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103702 request.traffic_annotation =
3703 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543704
3705 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493706 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3707 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093708 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543709
bnc691fda62016-08-12 00:43:163710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543711
3712 // Since we have proxy, should try to establish tunnel.
3713 MockWrite data_writes1[] = {
3714 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173715 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543716 "Proxy-Connection: keep-alive\r\n\r\n"),
3717 };
3718
3719 // The proxy responds to the connect with a 407, using a persistent
3720 // connection.
3721 MockRead data_reads1[] = {
3722 // No credentials.
3723 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3724 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3725 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3726 // Server hands up in the middle of the body.
3727 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3728 };
3729
3730 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163731 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543732 // be issuing -- the final header line contains the credentials.
3733 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173734 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543735 "Proxy-Connection: keep-alive\r\n"
3736 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3737
3738 MockWrite("GET / HTTP/1.1\r\n"
3739 "Host: www.example.org\r\n"
3740 "Connection: keep-alive\r\n\r\n"),
3741 };
3742
3743 MockRead data_reads2[] = {
3744 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3745
3746 MockRead("HTTP/1.1 200 OK\r\n"),
3747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3748 MockRead("Content-Length: 5\r\n\r\n"),
3749 MockRead(SYNCHRONOUS, "hello"),
3750 };
3751
3752 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3753 data_writes1, arraysize(data_writes1));
3754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3755 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3756 data_writes2, arraysize(data_writes2));
3757 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3758 SSLSocketDataProvider ssl(ASYNC, OK);
3759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3760
3761 TestCompletionCallback callback;
3762
tfarina42834112016-09-22 13:38:203763 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013764 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543765
bnc691fda62016-08-12 00:43:163766 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543767 ASSERT_TRUE(response);
3768 ASSERT_TRUE(response->headers);
3769 EXPECT_TRUE(response->headers->IsKeepAlive());
3770 EXPECT_EQ(407, response->headers->response_code());
3771 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3772
bnc691fda62016-08-12 00:43:163773 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013774 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543775
bnc691fda62016-08-12 00:43:163776 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543777 ASSERT_TRUE(response);
3778 ASSERT_TRUE(response->headers);
3779 EXPECT_TRUE(response->headers->IsKeepAlive());
3780 EXPECT_EQ(200, response->headers->response_code());
3781 std::string body;
bnc691fda62016-08-12 00:43:163782 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543783 EXPECT_EQ("hello", body);
3784}
3785
[email protected]a8e9b162009-03-12 00:06:443786// Test that we don't read the response body when we fail to establish a tunnel,
3787// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013788TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273789 HttpRequestInfo request;
3790 request.method = "GET";
bncce36dca22015-04-21 22:11:233791 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103792 request.traffic_annotation =
3793 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273794
[email protected]a8e9b162009-03-12 00:06:443795 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493796 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3797 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443798
danakj1fd259a02016-04-16 03:17:093799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443800
bnc691fda62016-08-12 00:43:163801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443802
[email protected]a8e9b162009-03-12 00:06:443803 // Since we have proxy, should try to establish tunnel.
3804 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173805 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3806 "Host: www.example.org:443\r\n"
3807 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443808 };
3809
3810 // The proxy responds to the connect with a 407.
3811 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243812 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3813 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3814 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233815 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243816 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443817 };
3818
[email protected]31a2bfe2010-02-09 08:03:393819 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3820 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073821 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443822
[email protected]49639fa2011-12-20 23:22:413823 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443824
tfarina42834112016-09-22 13:38:203825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443827
3828 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013829 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443830
bnc691fda62016-08-12 00:43:163831 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243832 ASSERT_TRUE(response);
3833 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443834 EXPECT_TRUE(response->headers->IsKeepAlive());
3835 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423836 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443837
3838 std::string response_data;
bnc691fda62016-08-12 00:43:163839 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013840 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183841
3842 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313843 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443844}
3845
ttuttle7933c112015-01-06 00:55:243846// Test that we don't pass extraneous headers from the proxy's response to the
3847// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013848TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243849 HttpRequestInfo request;
3850 request.method = "GET";
bncce36dca22015-04-21 22:11:233851 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103852 request.traffic_annotation =
3853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243854
3855 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493856 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3857 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243858
danakj1fd259a02016-04-16 03:17:093859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243860
bnc691fda62016-08-12 00:43:163861 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243862
3863 // Since we have proxy, should try to establish tunnel.
3864 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173865 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3866 "Host: www.example.org:443\r\n"
3867 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243868 };
3869
3870 // The proxy responds to the connect with a 407.
3871 MockRead data_reads[] = {
3872 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3873 MockRead("X-Foo: bar\r\n"),
3874 MockRead("Set-Cookie: foo=bar\r\n"),
3875 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3876 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233877 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243878 };
3879
3880 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3881 arraysize(data_writes));
3882 session_deps_.socket_factory->AddSocketDataProvider(&data);
3883
3884 TestCompletionCallback callback;
3885
tfarina42834112016-09-22 13:38:203886 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243888
3889 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013890 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243891
bnc691fda62016-08-12 00:43:163892 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243893 ASSERT_TRUE(response);
3894 ASSERT_TRUE(response->headers);
3895 EXPECT_TRUE(response->headers->IsKeepAlive());
3896 EXPECT_EQ(407, response->headers->response_code());
3897 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3898 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3899 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3900
3901 std::string response_data;
bnc691fda62016-08-12 00:43:163902 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013903 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243904
3905 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3906 session->CloseAllConnections();
3907}
3908
[email protected]8fdbcd22010-05-05 02:54:523909// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3910// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013911TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523912 HttpRequestInfo request;
3913 request.method = "GET";
bncce36dca22015-04-21 22:11:233914 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103915 request.traffic_annotation =
3916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523917
[email protected]cb9bf6ca2011-01-28 13:15:273918 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273921
[email protected]8fdbcd22010-05-05 02:54:523922 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233923 MockWrite(
3924 "GET / HTTP/1.1\r\n"
3925 "Host: www.example.org\r\n"
3926 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523927 };
3928
3929 MockRead data_reads1[] = {
3930 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3931 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3932 // Large content-length -- won't matter, as connection will be reset.
3933 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063934 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523935 };
3936
3937 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3938 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073939 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523940
[email protected]49639fa2011-12-20 23:22:413941 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523942
tfarina42834112016-09-22 13:38:203943 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523945
3946 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013947 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523948}
3949
[email protected]7a67a8152010-11-05 18:31:103950// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3951// through a non-authenticating proxy. The request should fail with
3952// ERR_UNEXPECTED_PROXY_AUTH.
3953// Note that it is impossible to detect if an HTTP server returns a 407 through
3954// a non-authenticating proxy - there is nothing to indicate whether the
3955// response came from the proxy or the server, so it is treated as if the proxy
3956// issued the challenge.
bncd16676a2016-07-20 16:23:013957TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273958 HttpRequestInfo request;
3959 request.method = "GET";
bncce36dca22015-04-21 22:11:233960 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103961 request.traffic_annotation =
3962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273963
Ramin Halavatica8d5252018-03-12 05:33:493964 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3965 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513966 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073967 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103969
[email protected]7a67a8152010-11-05 18:31:103970 // Since we have proxy, should try to establish tunnel.
3971 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173972 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3973 "Host: www.example.org:443\r\n"
3974 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103975
rsleevidb16bb02015-11-12 23:47:173976 MockWrite("GET / HTTP/1.1\r\n"
3977 "Host: www.example.org\r\n"
3978 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103979 };
3980
3981 MockRead data_reads1[] = {
3982 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3983
3984 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3985 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3986 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063987 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103988 };
3989
3990 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3991 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073992 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063993 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103995
[email protected]49639fa2011-12-20 23:22:413996 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103997
bnc691fda62016-08-12 00:43:163998 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103999
bnc691fda62016-08-12 00:43:164000 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104002
4003 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014004 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464005 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404006 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104007 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004008 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4009 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104010 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404011 entries, pos,
mikecirone8b85c432016-09-08 19:11:004012 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4013 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104014}
[email protected]2df19bb2010-08-25 20:13:464015
mmenke2a1781d2015-10-07 19:25:334016// Test a proxy auth scheme that allows default credentials and a proxy server
4017// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014018TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334019 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4020 HttpRequestInfo request;
4021 request.method = "GET";
4022 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104023 request.traffic_annotation =
4024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334025
4026 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594027 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494028 ProxyResolutionService::CreateFixedFromPacResult(
4029 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334030
Jeremy Roman0579ed62017-08-29 15:56:194031 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334032 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194033 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334034 mock_handler->set_allows_default_credentials(true);
4035 auth_handler_factory->AddMockHandler(mock_handler.release(),
4036 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484037 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334038
4039 // Add NetLog just so can verify load timing information gets a NetLog ID.
4040 NetLog net_log;
4041 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094042 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334043
4044 // Since we have proxy, should try to establish tunnel.
4045 MockWrite data_writes1[] = {
4046 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174047 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334048 "Proxy-Connection: keep-alive\r\n\r\n"),
4049 };
4050
4051 // The proxy responds to the connect with a 407, using a non-persistent
4052 // connection.
4053 MockRead data_reads1[] = {
4054 // No credentials.
4055 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4056 MockRead("Proxy-Authenticate: Mock\r\n"),
4057 MockRead("Proxy-Connection: close\r\n\r\n"),
4058 };
4059
4060 // Since the first connection couldn't be reused, need to establish another
4061 // once given credentials.
4062 MockWrite data_writes2[] = {
4063 // After calling trans->RestartWithAuth(), this is the request we should
4064 // be issuing -- the final header line contains the credentials.
4065 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174066 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334067 "Proxy-Connection: keep-alive\r\n"
4068 "Proxy-Authorization: auth_token\r\n\r\n"),
4069
4070 MockWrite("GET / HTTP/1.1\r\n"
4071 "Host: www.example.org\r\n"
4072 "Connection: keep-alive\r\n\r\n"),
4073 };
4074
4075 MockRead data_reads2[] = {
4076 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4077
4078 MockRead("HTTP/1.1 200 OK\r\n"),
4079 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4080 MockRead("Content-Length: 5\r\n\r\n"),
4081 MockRead(SYNCHRONOUS, "hello"),
4082 };
4083
4084 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4085 data_writes1, arraysize(data_writes1));
4086 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4087 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4088 data_writes2, arraysize(data_writes2));
4089 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4090 SSLSocketDataProvider ssl(ASYNC, OK);
4091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4092
bnc87dcefc2017-05-25 12:47:584093 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194094 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334095
4096 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204097 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014098 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334099
4100 const HttpResponseInfo* response = trans->GetResponseInfo();
4101 ASSERT_TRUE(response);
4102 ASSERT_TRUE(response->headers);
4103 EXPECT_FALSE(response->headers->IsKeepAlive());
4104 EXPECT_EQ(407, response->headers->response_code());
4105 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4106 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524107 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334108
4109 LoadTimingInfo load_timing_info;
4110 // CONNECT requests and responses are handled at the connect job level, so
4111 // the transaction does not yet have a connection.
4112 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4113
4114 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014115 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334116 response = trans->GetResponseInfo();
4117 ASSERT_TRUE(response);
4118 ASSERT_TRUE(response->headers);
4119 EXPECT_TRUE(response->headers->IsKeepAlive());
4120 EXPECT_EQ(200, response->headers->response_code());
4121 EXPECT_EQ(5, response->headers->GetContentLength());
4122 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4123
4124 // The password prompt info should not be set.
4125 EXPECT_FALSE(response->auth_challenge);
4126
4127 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4128 TestLoadTimingNotReusedWithPac(load_timing_info,
4129 CONNECT_TIMING_HAS_SSL_TIMES);
4130
4131 trans.reset();
4132 session->CloseAllConnections();
4133}
4134
4135// Test a proxy auth scheme that allows default credentials and a proxy server
4136// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014137TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334138 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4139 HttpRequestInfo request;
4140 request.method = "GET";
4141 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104142 request.traffic_annotation =
4143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334144
4145 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594146 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494147 ProxyResolutionService::CreateFixedFromPacResult(
4148 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334149
Jeremy Roman0579ed62017-08-29 15:56:194150 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334151 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194152 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334153 mock_handler->set_allows_default_credentials(true);
4154 auth_handler_factory->AddMockHandler(mock_handler.release(),
4155 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484156 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334157
4158 // Add NetLog just so can verify load timing information gets a NetLog ID.
4159 NetLog net_log;
4160 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094161 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334162
4163 // Should try to establish tunnel.
4164 MockWrite data_writes1[] = {
4165 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174166 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334167 "Proxy-Connection: keep-alive\r\n\r\n"),
4168
4169 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174170 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334171 "Proxy-Connection: keep-alive\r\n"
4172 "Proxy-Authorization: auth_token\r\n\r\n"),
4173 };
4174
4175 // The proxy responds to the connect with a 407, using a non-persistent
4176 // connection.
4177 MockRead data_reads1[] = {
4178 // No credentials.
4179 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4180 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4181 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4182 };
4183
4184 // Since the first connection was closed, need to establish another once given
4185 // credentials.
4186 MockWrite data_writes2[] = {
4187 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174188 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334189 "Proxy-Connection: keep-alive\r\n"
4190 "Proxy-Authorization: auth_token\r\n\r\n"),
4191
4192 MockWrite("GET / HTTP/1.1\r\n"
4193 "Host: www.example.org\r\n"
4194 "Connection: keep-alive\r\n\r\n"),
4195 };
4196
4197 MockRead data_reads2[] = {
4198 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4199
4200 MockRead("HTTP/1.1 200 OK\r\n"),
4201 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4202 MockRead("Content-Length: 5\r\n\r\n"),
4203 MockRead(SYNCHRONOUS, "hello"),
4204 };
4205
4206 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4207 data_writes1, arraysize(data_writes1));
4208 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4209 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4210 data_writes2, arraysize(data_writes2));
4211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4212 SSLSocketDataProvider ssl(ASYNC, OK);
4213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4214
bnc87dcefc2017-05-25 12:47:584215 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194216 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334217
4218 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204219 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014220 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334221
4222 const HttpResponseInfo* response = trans->GetResponseInfo();
4223 ASSERT_TRUE(response);
4224 ASSERT_TRUE(response->headers);
4225 EXPECT_TRUE(response->headers->IsKeepAlive());
4226 EXPECT_EQ(407, response->headers->response_code());
4227 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4228 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4229 EXPECT_FALSE(response->auth_challenge);
4230
4231 LoadTimingInfo load_timing_info;
4232 // CONNECT requests and responses are handled at the connect job level, so
4233 // the transaction does not yet have a connection.
4234 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4235
4236 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014237 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334238
4239 response = trans->GetResponseInfo();
4240 ASSERT_TRUE(response);
4241 ASSERT_TRUE(response->headers);
4242 EXPECT_TRUE(response->headers->IsKeepAlive());
4243 EXPECT_EQ(200, response->headers->response_code());
4244 EXPECT_EQ(5, response->headers->GetContentLength());
4245 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4246
4247 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524248 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334249
4250 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4251 TestLoadTimingNotReusedWithPac(load_timing_info,
4252 CONNECT_TIMING_HAS_SSL_TIMES);
4253
4254 trans.reset();
4255 session->CloseAllConnections();
4256}
4257
4258// Test a proxy auth scheme that allows default credentials and a proxy server
4259// that hangs up when credentials are initially sent, and hangs up again when
4260// they are retried.
bncd16676a2016-07-20 16:23:014261TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334262 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4263 HttpRequestInfo request;
4264 request.method = "GET";
4265 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104266 request.traffic_annotation =
4267 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334268
4269 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594270 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494271 ProxyResolutionService::CreateFixedFromPacResult(
4272 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334273
Jeremy Roman0579ed62017-08-29 15:56:194274 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334275 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194276 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334277 mock_handler->set_allows_default_credentials(true);
4278 auth_handler_factory->AddMockHandler(mock_handler.release(),
4279 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484280 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334281
4282 // Add NetLog just so can verify load timing information gets a NetLog ID.
4283 NetLog net_log;
4284 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094285 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334286
4287 // Should try to establish tunnel.
4288 MockWrite data_writes1[] = {
4289 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174290 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334291 "Proxy-Connection: keep-alive\r\n\r\n"),
4292
4293 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174294 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334295 "Proxy-Connection: keep-alive\r\n"
4296 "Proxy-Authorization: auth_token\r\n\r\n"),
4297 };
4298
4299 // The proxy responds to the connect with a 407, and then hangs up after the
4300 // second request is sent.
4301 MockRead data_reads1[] = {
4302 // No credentials.
4303 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4304 MockRead("Content-Length: 0\r\n"),
4305 MockRead("Proxy-Connection: keep-alive\r\n"),
4306 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4307 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4308 };
4309
4310 // HttpNetworkTransaction sees a reused connection that was closed with
4311 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4312 // request.
4313 MockWrite data_writes2[] = {
4314 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174315 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334316 "Proxy-Connection: keep-alive\r\n\r\n"),
4317 };
4318
4319 // The proxy, having had more than enough of us, just hangs up.
4320 MockRead data_reads2[] = {
4321 // No credentials.
4322 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4323 };
4324
4325 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4326 data_writes1, arraysize(data_writes1));
4327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4328 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4329 data_writes2, arraysize(data_writes2));
4330 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4331
bnc87dcefc2017-05-25 12:47:584332 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194333 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334334
4335 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204336 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014337 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334338
4339 const HttpResponseInfo* response = trans->GetResponseInfo();
4340 ASSERT_TRUE(response);
4341 ASSERT_TRUE(response->headers);
4342 EXPECT_TRUE(response->headers->IsKeepAlive());
4343 EXPECT_EQ(407, response->headers->response_code());
4344 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4345 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4346 EXPECT_FALSE(response->auth_challenge);
4347
4348 LoadTimingInfo load_timing_info;
4349 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4350
4351 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014352 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334353
4354 trans.reset();
4355 session->CloseAllConnections();
4356}
4357
4358// Test a proxy auth scheme that allows default credentials and a proxy server
4359// that hangs up when credentials are initially sent, and sends a challenge
4360// again they are retried.
bncd16676a2016-07-20 16:23:014361TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334362 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4363 HttpRequestInfo request;
4364 request.method = "GET";
4365 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104366 request.traffic_annotation =
4367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334368
4369 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594370 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494371 ProxyResolutionService::CreateFixedFromPacResult(
4372 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334373
Jeremy Roman0579ed62017-08-29 15:56:194374 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334375 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194376 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334377 mock_handler->set_allows_default_credentials(true);
4378 auth_handler_factory->AddMockHandler(mock_handler.release(),
4379 HttpAuth::AUTH_PROXY);
4380 // Add another handler for the second challenge. It supports default
4381 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194382 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334383 mock_handler->set_allows_default_credentials(true);
4384 auth_handler_factory->AddMockHandler(mock_handler.release(),
4385 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484386 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334387
4388 // Add NetLog just so can verify load timing information gets a NetLog ID.
4389 NetLog net_log;
4390 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094391 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334392
4393 // Should try to establish tunnel.
4394 MockWrite data_writes1[] = {
4395 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174396 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334397 "Proxy-Connection: keep-alive\r\n\r\n"),
4398 };
4399
4400 // The proxy responds to the connect with a 407, using a non-persistent
4401 // connection.
4402 MockRead data_reads1[] = {
4403 // No credentials.
4404 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4405 MockRead("Proxy-Authenticate: Mock\r\n"),
4406 MockRead("Proxy-Connection: close\r\n\r\n"),
4407 };
4408
4409 // Since the first connection was closed, need to establish another once given
4410 // credentials.
4411 MockWrite data_writes2[] = {
4412 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174413 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334414 "Proxy-Connection: keep-alive\r\n"
4415 "Proxy-Authorization: auth_token\r\n\r\n"),
4416 };
4417
4418 MockRead data_reads2[] = {
4419 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4420 MockRead("Proxy-Authenticate: Mock\r\n"),
4421 MockRead("Proxy-Connection: close\r\n\r\n"),
4422 };
4423
4424 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4425 data_writes1, arraysize(data_writes1));
4426 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4427 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4428 data_writes2, arraysize(data_writes2));
4429 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4430 SSLSocketDataProvider ssl(ASYNC, OK);
4431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4432
bnc87dcefc2017-05-25 12:47:584433 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194434 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334435
4436 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204437 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014438 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334439
4440 const HttpResponseInfo* response = trans->GetResponseInfo();
4441 ASSERT_TRUE(response);
4442 ASSERT_TRUE(response->headers);
4443 EXPECT_EQ(407, response->headers->response_code());
4444 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4445 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4446 EXPECT_FALSE(response->auth_challenge);
4447
4448 LoadTimingInfo load_timing_info;
4449 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4450
4451 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014452 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334453 response = trans->GetResponseInfo();
4454 ASSERT_TRUE(response);
4455 ASSERT_TRUE(response->headers);
4456 EXPECT_EQ(407, response->headers->response_code());
4457 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4458 EXPECT_TRUE(response->auth_challenge);
4459
4460 trans.reset();
4461 session->CloseAllConnections();
4462}
4463
asankae2257db2016-10-11 22:03:164464// A more nuanced test than GenerateAuthToken test which asserts that
4465// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4466// unnecessarily invalidated, and that if the server co-operates, the
4467// authentication handshake can continue with the same scheme but with a
4468// different identity.
4469TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4470 HttpRequestInfo request;
4471 request.method = "GET";
4472 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104473 request.traffic_annotation =
4474 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164475
Jeremy Roman0579ed62017-08-29 15:56:194476 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164477 auth_handler_factory->set_do_init_from_challenge(true);
4478
4479 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194480 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164481 mock_handler->set_allows_default_credentials(true);
4482 mock_handler->set_allows_explicit_credentials(true);
4483 mock_handler->set_connection_based(true);
4484 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4485 auth_handler_factory->AddMockHandler(mock_handler.release(),
4486 HttpAuth::AUTH_SERVER);
4487
4488 // Add another handler for the second challenge. It supports default
4489 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194490 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164491 mock_handler->set_allows_default_credentials(true);
4492 mock_handler->set_allows_explicit_credentials(true);
4493 mock_handler->set_connection_based(true);
4494 auth_handler_factory->AddMockHandler(mock_handler.release(),
4495 HttpAuth::AUTH_SERVER);
4496 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4497
4498 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4499
4500 MockWrite data_writes1[] = {
4501 MockWrite("GET / HTTP/1.1\r\n"
4502 "Host: www.example.org\r\n"
4503 "Connection: keep-alive\r\n\r\n"),
4504 };
4505
4506 MockRead data_reads1[] = {
4507 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4508 "WWW-Authenticate: Mock\r\n"
4509 "Connection: keep-alive\r\n\r\n"),
4510 };
4511
4512 // Identical to data_writes1[]. The AuthHandler encounters a
4513 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4514 // transaction procceds without an authorization header.
4515 MockWrite data_writes2[] = {
4516 MockWrite("GET / HTTP/1.1\r\n"
4517 "Host: www.example.org\r\n"
4518 "Connection: keep-alive\r\n\r\n"),
4519 };
4520
4521 MockRead data_reads2[] = {
4522 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4523 "WWW-Authenticate: Mock\r\n"
4524 "Connection: keep-alive\r\n\r\n"),
4525 };
4526
4527 MockWrite data_writes3[] = {
4528 MockWrite("GET / HTTP/1.1\r\n"
4529 "Host: www.example.org\r\n"
4530 "Connection: keep-alive\r\n"
4531 "Authorization: auth_token\r\n\r\n"),
4532 };
4533
4534 MockRead data_reads3[] = {
4535 MockRead("HTTP/1.1 200 OK\r\n"
4536 "Content-Length: 5\r\n"
4537 "Content-Type: text/plain\r\n"
4538 "Connection: keep-alive\r\n\r\n"
4539 "Hello"),
4540 };
4541
4542 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4543 data_writes1, arraysize(data_writes1));
4544 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4545
4546 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4547 data_writes2, arraysize(data_writes2));
4548 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4549
4550 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4551 data_writes3, arraysize(data_writes3));
4552 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4553
bnc87dcefc2017-05-25 12:47:584554 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194555 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164556
4557 TestCompletionCallback callback;
4558 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4559 EXPECT_THAT(callback.GetResult(rv), IsOk());
4560
4561 const HttpResponseInfo* response = trans->GetResponseInfo();
4562 ASSERT_TRUE(response);
4563 ASSERT_TRUE(response->headers);
4564 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4565
4566 // The following three tests assert that an authentication challenge was
4567 // received and that the stack is ready to respond to the challenge using
4568 // ambient credentials.
4569 EXPECT_EQ(401, response->headers->response_code());
4570 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4571 EXPECT_FALSE(response->auth_challenge);
4572
4573 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4574 EXPECT_THAT(callback.GetResult(rv), IsOk());
4575 response = trans->GetResponseInfo();
4576 ASSERT_TRUE(response);
4577 ASSERT_TRUE(response->headers);
4578
4579 // The following three tests assert that an authentication challenge was
4580 // received and that the stack needs explicit credentials before it is ready
4581 // to respond to the challenge.
4582 EXPECT_EQ(401, response->headers->response_code());
4583 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4584 EXPECT_TRUE(response->auth_challenge);
4585
4586 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4587 EXPECT_THAT(callback.GetResult(rv), IsOk());
4588 response = trans->GetResponseInfo();
4589 ASSERT_TRUE(response);
4590 ASSERT_TRUE(response->headers);
4591 EXPECT_EQ(200, response->headers->response_code());
4592
4593 trans.reset();
4594 session->CloseAllConnections();
4595}
4596
Matt Menked1eb6d42018-01-17 04:54:064597// Proxy resolver that returns a proxy with the same host and port for different
4598// schemes, based on the path of the URL being requests.
4599class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4600 public:
4601 SameProxyWithDifferentSchemesProxyResolver() {}
4602 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4603
4604 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4605
4606 static HostPortPair ProxyHostPortPair() {
4607 return HostPortPair::FromString(ProxyHostPortPairAsString());
4608 }
4609
4610 // ProxyResolver implementation.
4611 int GetProxyForURL(const GURL& url,
4612 ProxyInfo* results,
4613 const CompletionCallback& callback,
4614 std::unique_ptr<Request>* request,
4615 const NetLogWithSource& /*net_log*/) override {
4616 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574617 results->set_traffic_annotation(
4618 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064619 if (url.path() == "/socks4") {
4620 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4621 return OK;
4622 }
4623 if (url.path() == "/socks5") {
4624 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4625 return OK;
4626 }
4627 if (url.path() == "/http") {
4628 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4629 return OK;
4630 }
4631 if (url.path() == "/https") {
4632 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4633 return OK;
4634 }
4635 NOTREACHED();
4636 return ERR_NOT_IMPLEMENTED;
4637 }
4638
4639 private:
4640 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4641};
4642
4643class SameProxyWithDifferentSchemesProxyResolverFactory
4644 : public ProxyResolverFactory {
4645 public:
4646 SameProxyWithDifferentSchemesProxyResolverFactory()
4647 : ProxyResolverFactory(false) {}
4648
Lily Houghton99597862018-03-07 16:40:424649 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4650 std::unique_ptr<ProxyResolver>* resolver,
4651 const CompletionCallback& callback,
4652 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064653 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4654 return OK;
4655 }
4656
4657 private:
4658 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4659};
4660
4661// Check that when different proxy schemes are all applied to a proxy at the
4662// same address, the sonnections are not grouped together. i.e., a request to
4663// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4664// request to foo.com using proxy.com as an HTTP proxy.
4665TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494666 session_deps_.proxy_resolution_service =
4667 std::make_unique<ProxyResolutionService>(
4668 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4669 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4670 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4671 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064672
4673 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4674
4675 MockWrite socks_writes[] = {
4676 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4677 kSOCKS4OkRequestLocalHostPort80Length),
4678 MockWrite(SYNCHRONOUS,
4679 "GET /socks4 HTTP/1.1\r\n"
4680 "Host: test\r\n"
4681 "Connection: keep-alive\r\n\r\n"),
4682 };
4683 MockRead socks_reads[] = {
4684 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4685 MockRead("HTTP/1.0 200 OK\r\n"
4686 "Connection: keep-alive\r\n"
4687 "Content-Length: 15\r\n\r\n"
4688 "SOCKS4 Response"),
4689 };
4690 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4691 socks_writes, arraysize(socks_writes));
4692 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4693
4694 const char kSOCKS5Request[] = {
4695 0x05, // Version
4696 0x01, // Command (CONNECT)
4697 0x00, // Reserved
4698 0x03, // Address type (DOMAINNAME)
4699 0x04, // Length of domain (4)
4700 't', 'e', 's', 't', // Domain string
4701 0x00, 0x50, // 16-bit port (80)
4702 };
4703 MockWrite socks5_writes[] = {
4704 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4705 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4706 MockWrite(SYNCHRONOUS,
4707 "GET /socks5 HTTP/1.1\r\n"
4708 "Host: test\r\n"
4709 "Connection: keep-alive\r\n\r\n"),
4710 };
4711 MockRead socks5_reads[] = {
4712 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4713 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4714 MockRead("HTTP/1.0 200 OK\r\n"
4715 "Connection: keep-alive\r\n"
4716 "Content-Length: 15\r\n\r\n"
4717 "SOCKS5 Response"),
4718 };
4719 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4720 socks5_writes, arraysize(socks5_writes));
4721 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4722
4723 MockWrite http_writes[] = {
4724 MockWrite(SYNCHRONOUS,
4725 "GET http://test/http HTTP/1.1\r\n"
4726 "Host: test\r\n"
4727 "Proxy-Connection: keep-alive\r\n\r\n"),
4728 };
4729 MockRead http_reads[] = {
4730 MockRead("HTTP/1.1 200 OK\r\n"
4731 "Proxy-Connection: keep-alive\r\n"
4732 "Content-Length: 13\r\n\r\n"
4733 "HTTP Response"),
4734 };
4735 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4736 http_writes, arraysize(http_writes));
4737 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4738
4739 MockWrite https_writes[] = {
4740 MockWrite(SYNCHRONOUS,
4741 "GET http://test/https HTTP/1.1\r\n"
4742 "Host: test\r\n"
4743 "Proxy-Connection: keep-alive\r\n\r\n"),
4744 };
4745 MockRead https_reads[] = {
4746 MockRead("HTTP/1.1 200 OK\r\n"
4747 "Proxy-Connection: keep-alive\r\n"
4748 "Content-Length: 14\r\n\r\n"
4749 "HTTPS Response"),
4750 };
4751 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4752 https_writes, arraysize(https_writes));
4753 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4754 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4756
4757 struct TestCase {
4758 GURL url;
4759 std::string expected_response;
4760 // How many idle sockets there should be in the SOCKS proxy socket pool
4761 // after the test.
4762 int expected_idle_socks_sockets;
4763 // How many idle sockets there should be in the HTTP proxy socket pool after
4764 // the test.
4765 int expected_idle_http_sockets;
4766 } const kTestCases[] = {
4767 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4768 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4769 {GURL("http://test/http"), "HTTP Response", 2, 1},
4770 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4771 };
4772
4773 for (const auto& test_case : kTestCases) {
4774 HttpRequestInfo request;
4775 request.method = "GET";
4776 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:104777 request.traffic_annotation =
4778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064779 std::unique_ptr<HttpNetworkTransaction> trans =
4780 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4781 session.get());
4782 TestCompletionCallback callback;
4783 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4784 EXPECT_THAT(callback.GetResult(rv), IsOk());
4785
4786 const HttpResponseInfo* response = trans->GetResponseInfo();
4787 ASSERT_TRUE(response);
4788 ASSERT_TRUE(response->headers);
4789 EXPECT_EQ(200, response->headers->response_code());
4790 std::string response_data;
4791 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4792 EXPECT_EQ(test_case.expected_response, response_data);
4793
4794 // Return the socket to the socket pool, so can make sure it's not used for
4795 // the next requests.
4796 trans.reset();
4797 base::RunLoop().RunUntilIdle();
4798
4799 // Check the number of idle sockets in the pool, to make sure that used
4800 // sockets are indeed being returned to the socket pool. If each request
4801 // doesn't return an idle socket to the pool, the test would incorrectly
4802 // pass.
4803 EXPECT_EQ(
4804 test_case.expected_idle_socks_sockets,
4805 session
4806 ->GetSocketPoolForSOCKSProxy(
4807 HttpNetworkSession::NORMAL_SOCKET_POOL,
4808 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4809 ->IdleSocketCount());
4810 EXPECT_EQ(
4811 test_case.expected_idle_http_sockets,
4812 session
4813 ->GetSocketPoolForHTTPProxy(
4814 HttpNetworkSession::NORMAL_SOCKET_POOL,
4815 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4816 ->IdleSocketCount());
4817 }
4818}
4819
[email protected]029c83b62013-01-24 05:28:204820// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014821TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204822 HttpRequestInfo request1;
4823 request1.method = "GET";
bncce36dca22015-04-21 22:11:234824 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104825 request1.traffic_annotation =
4826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204827
4828 HttpRequestInfo request2;
4829 request2.method = "GET";
bncce36dca22015-04-21 22:11:234830 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104831 request2.traffic_annotation =
4832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204833
4834 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494835 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4836 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514837 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074838 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204840
4841 // Since we have proxy, should try to establish tunnel.
4842 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174843 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4844 "Host: www.example.org:443\r\n"
4845 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204846
rsleevidb16bb02015-11-12 23:47:174847 MockWrite("GET /1 HTTP/1.1\r\n"
4848 "Host: www.example.org\r\n"
4849 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204850
rsleevidb16bb02015-11-12 23:47:174851 MockWrite("GET /2 HTTP/1.1\r\n"
4852 "Host: www.example.org\r\n"
4853 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204854 };
4855
4856 // The proxy responds to the connect with a 407, using a persistent
4857 // connection.
4858 MockRead data_reads1[] = {
4859 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4860
4861 MockRead("HTTP/1.1 200 OK\r\n"),
4862 MockRead("Content-Length: 1\r\n\r\n"),
4863 MockRead(SYNCHRONOUS, "1"),
4864
4865 MockRead("HTTP/1.1 200 OK\r\n"),
4866 MockRead("Content-Length: 2\r\n\r\n"),
4867 MockRead(SYNCHRONOUS, "22"),
4868 };
4869
4870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4871 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204873 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204875
4876 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584877 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204879
4880 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204882
4883 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014884 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204885
4886 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524887 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474888 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524889 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204890 EXPECT_EQ(1, response1->headers->GetContentLength());
4891
4892 LoadTimingInfo load_timing_info1;
4893 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4894 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4895
4896 trans1.reset();
4897
4898 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584899 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194900 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204901
4902 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204904
4905 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014906 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204907
4908 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524909 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474910 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524911 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204912 EXPECT_EQ(2, response2->headers->GetContentLength());
4913
4914 LoadTimingInfo load_timing_info2;
4915 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4916 TestLoadTimingReused(load_timing_info2);
4917
4918 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4919
4920 trans2.reset();
4921 session->CloseAllConnections();
4922}
4923
4924// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014925TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204926 HttpRequestInfo request1;
4927 request1.method = "GET";
bncce36dca22015-04-21 22:11:234928 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104929 request1.traffic_annotation =
4930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204931
4932 HttpRequestInfo request2;
4933 request2.method = "GET";
bncce36dca22015-04-21 22:11:234934 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104935 request2.traffic_annotation =
4936 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204937
4938 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594939 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494940 ProxyResolutionService::CreateFixedFromPacResult(
4941 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514942 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074943 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204945
4946 // Since we have proxy, should try to establish tunnel.
4947 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174948 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4949 "Host: www.example.org:443\r\n"
4950 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204951
rsleevidb16bb02015-11-12 23:47:174952 MockWrite("GET /1 HTTP/1.1\r\n"
4953 "Host: www.example.org\r\n"
4954 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204955
rsleevidb16bb02015-11-12 23:47:174956 MockWrite("GET /2 HTTP/1.1\r\n"
4957 "Host: www.example.org\r\n"
4958 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204959 };
4960
4961 // The proxy responds to the connect with a 407, using a persistent
4962 // connection.
4963 MockRead data_reads1[] = {
4964 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4965
4966 MockRead("HTTP/1.1 200 OK\r\n"),
4967 MockRead("Content-Length: 1\r\n\r\n"),
4968 MockRead(SYNCHRONOUS, "1"),
4969
4970 MockRead("HTTP/1.1 200 OK\r\n"),
4971 MockRead("Content-Length: 2\r\n\r\n"),
4972 MockRead(SYNCHRONOUS, "22"),
4973 };
4974
4975 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4976 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074977 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204978 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074979 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204980
4981 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584982 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194983 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204984
4985 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204987
4988 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014989 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204990
4991 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524992 ASSERT_TRUE(response1);
4993 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204994 EXPECT_EQ(1, response1->headers->GetContentLength());
4995
4996 LoadTimingInfo load_timing_info1;
4997 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4998 TestLoadTimingNotReusedWithPac(load_timing_info1,
4999 CONNECT_TIMING_HAS_SSL_TIMES);
5000
5001 trans1.reset();
5002
5003 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585004 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195005 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205006
5007 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205009
5010 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015011 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205012
5013 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525014 ASSERT_TRUE(response2);
5015 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205016 EXPECT_EQ(2, response2->headers->GetContentLength());
5017
5018 LoadTimingInfo load_timing_info2;
5019 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5020 TestLoadTimingReusedWithPac(load_timing_info2);
5021
5022 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5023
5024 trans2.reset();
5025 session->CloseAllConnections();
5026}
5027
[email protected]2df19bb2010-08-25 20:13:465028// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015029TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275030 HttpRequestInfo request;
5031 request.method = "GET";
bncce36dca22015-04-21 22:11:235032 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105033 request.traffic_annotation =
5034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275035
[email protected]2df19bb2010-08-25 20:13:465036 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495037 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5038 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515039 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075040 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465042
[email protected]2df19bb2010-08-25 20:13:465043 // Since we have proxy, should use full url
5044 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235045 MockWrite(
5046 "GET http://www.example.org/ HTTP/1.1\r\n"
5047 "Host: www.example.org\r\n"
5048 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465049 };
5050
5051 MockRead data_reads1[] = {
5052 MockRead("HTTP/1.1 200 OK\r\n"),
5053 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5054 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065055 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465056 };
5057
5058 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5059 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065061 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465063
[email protected]49639fa2011-12-20 23:22:415064 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465065
bnc691fda62016-08-12 00:43:165066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505067
bnc691fda62016-08-12 00:43:165068 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465070
5071 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015072 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465073
[email protected]58e32bb2013-01-21 18:23:255074 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165075 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255076 TestLoadTimingNotReused(load_timing_info,
5077 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5078
bnc691fda62016-08-12 00:43:165079 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525080 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465081
tbansal2ecbbc72016-10-06 17:15:475082 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465083 EXPECT_TRUE(response->headers->IsKeepAlive());
5084 EXPECT_EQ(200, response->headers->response_code());
5085 EXPECT_EQ(100, response->headers->GetContentLength());
5086 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5087
5088 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525089 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465090}
5091
[email protected]7642b5ae2010-09-01 20:55:175092// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015093TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275094 HttpRequestInfo request;
5095 request.method = "GET";
bncce36dca22015-04-21 22:11:235096 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105097 request.traffic_annotation =
5098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275099
[email protected]7642b5ae2010-09-01 20:55:175100 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495101 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5102 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515103 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075104 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175106
bncce36dca22015-04-21 22:11:235107 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415108 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455109 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415110 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175111
bnc42331402016-07-25 13:36:155112 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415113 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175114 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415115 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175116 };
5117
rch8e6c6c42015-05-01 14:05:135118 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5119 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075120 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175121
[email protected]8ddf8322012-02-23 18:08:065122 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365123 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175125
[email protected]49639fa2011-12-20 23:22:415126 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175127
bnc691fda62016-08-12 00:43:165128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505129
bnc691fda62016-08-12 00:43:165130 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175132
5133 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015134 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175135
[email protected]58e32bb2013-01-21 18:23:255136 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165137 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255138 TestLoadTimingNotReused(load_timing_info,
5139 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5140
bnc691fda62016-08-12 00:43:165141 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525142 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475143 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525144 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025145 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175146
5147 std::string response_data;
bnc691fda62016-08-12 00:43:165148 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235149 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175150}
5151
[email protected]1c173852014-06-19 12:51:505152// Verifies that a session which races and wins against the owning transaction
5153// (completing prior to host resolution), doesn't fail the transaction.
5154// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015155TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505156 HttpRequestInfo request;
5157 request.method = "GET";
bncce36dca22015-04-21 22:11:235158 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105159 request.traffic_annotation =
5160 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505161
5162 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495163 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5164 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515165 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505166 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505168
bncce36dca22015-04-21 22:11:235169 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415170 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455171 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415172 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505173
bnc42331402016-07-25 13:36:155174 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415175 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505176 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415177 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505178 };
5179
rch8e6c6c42015-05-01 14:05:135180 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5181 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505182 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5183
5184 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365185 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5187
5188 TestCompletionCallback callback1;
5189
bnc691fda62016-08-12 00:43:165190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505191
5192 // Stall the hostname resolution begun by the transaction.
5193 session_deps_.host_resolver->set_synchronous_mode(false);
5194 session_deps_.host_resolver->set_ondemand_mode(true);
5195
bnc691fda62016-08-12 00:43:165196 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505198
5199 // Race a session to the proxy, which completes first.
5200 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045201 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5202 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505203 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525204 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505205
5206 // Unstall the resolution begun by the transaction.
5207 session_deps_.host_resolver->set_ondemand_mode(true);
5208 session_deps_.host_resolver->ResolveAllPending();
5209
5210 EXPECT_FALSE(callback1.have_result());
5211 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015212 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505213
bnc691fda62016-08-12 00:43:165214 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525215 ASSERT_TRUE(response);
5216 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025217 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505218
5219 std::string response_data;
bnc691fda62016-08-12 00:43:165220 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505221 EXPECT_EQ(kUploadData, response_data);
5222}
5223
[email protected]dc7bd1c52010-11-12 00:01:135224// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015225TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275226 HttpRequestInfo request;
5227 request.method = "GET";
bncce36dca22015-04-21 22:11:235228 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105229 request.traffic_annotation =
5230 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275231
[email protected]79cb5c12011-09-12 13:12:045232 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495233 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5234 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515235 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075236 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135238
[email protected]dc7bd1c52010-11-12 00:01:135239 // The first request will be a bare GET, the second request will be a
5240 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455241 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415242 SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485243 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385244 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135245 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465246 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135247 };
bncdf80d44fd2016-07-15 20:27:415248 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5249 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485250 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135251 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415252 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135253 };
5254
5255 // The first response is a 407 proxy authentication challenge, and the second
5256 // response will be a 200 response since the second request includes a valid
5257 // Authorization header.
5258 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465259 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135260 };
bnc42331402016-07-25 13:36:155261 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235262 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415263 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5264 SpdySerializedFrame body_authentication(
5265 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155266 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415267 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135268 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415269 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465270 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415271 CreateMockRead(resp_data, 4),
5272 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135273 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135274 };
5275
rch8e6c6c42015-05-01 14:05:135276 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5277 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075278 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135279
[email protected]8ddf8322012-02-23 18:08:065280 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365281 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135283
[email protected]49639fa2011-12-20 23:22:415284 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135285
bnc691fda62016-08-12 00:43:165286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135287
bnc691fda62016-08-12 00:43:165288 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135290
5291 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015292 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135293
bnc691fda62016-08-12 00:43:165294 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135295
wezca1070932016-05-26 20:30:525296 ASSERT_TRUE(response);
5297 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135298 EXPECT_EQ(407, response->headers->response_code());
5299 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435300 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135301
[email protected]49639fa2011-12-20 23:22:415302 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135303
bnc691fda62016-08-12 00:43:165304 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135306
5307 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015308 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135309
bnc691fda62016-08-12 00:43:165310 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135311
wezca1070932016-05-26 20:30:525312 ASSERT_TRUE(response_restart);
5313 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135314 EXPECT_EQ(200, response_restart->headers->response_code());
5315 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525316 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135317}
5318
[email protected]d9da5fe2010-10-13 22:37:165319// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015320TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275321 HttpRequestInfo request;
5322 request.method = "GET";
bncce36dca22015-04-21 22:11:235323 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105324 request.traffic_annotation =
5325 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275326
[email protected]d9da5fe2010-10-13 22:37:165327 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495328 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5329 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515330 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075331 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165333
bnc691fda62016-08-12 00:43:165334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165335
bncce36dca22015-04-21 22:11:235336 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415337 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235338 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5339 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165340
bncce36dca22015-04-21 22:11:235341 const char get[] =
5342 "GET / HTTP/1.1\r\n"
5343 "Host: www.example.org\r\n"
5344 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415345 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195346 spdy_util_.ConstructSpdyDataFrame(1, get, false));
bnc42331402016-07-25 13:36:155347 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165348 const char resp[] = "HTTP/1.1 200 OK\r\n"
5349 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415350 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195351 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
bncdf80d44fd2016-07-15 20:27:415352 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195353 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
bncdf80d44fd2016-07-15 20:27:415354 SpdySerializedFrame window_update(
5355 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045356
5357 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415358 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5359 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045360 };
5361
[email protected]d9da5fe2010-10-13 22:37:165362 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415363 CreateMockRead(conn_resp, 1, ASYNC),
5364 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5365 CreateMockRead(wrapped_body, 4, ASYNC),
5366 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135367 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165368 };
5369
rch8e6c6c42015-05-01 14:05:135370 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5371 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075372 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165373
[email protected]8ddf8322012-02-23 18:08:065374 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365375 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065377 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165379
[email protected]49639fa2011-12-20 23:22:415380 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165381
bnc691fda62016-08-12 00:43:165382 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015383 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165384
5385 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015386 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165387
[email protected]58e32bb2013-01-21 18:23:255388 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165389 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255390 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5391
bnc691fda62016-08-12 00:43:165392 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525393 ASSERT_TRUE(response);
5394 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165395 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5396
5397 std::string response_data;
bnc691fda62016-08-12 00:43:165398 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165399 EXPECT_EQ("1234567890", response_data);
5400}
5401
5402// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015403TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5404 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385405
[email protected]cb9bf6ca2011-01-28 13:15:275406 HttpRequestInfo request;
5407 request.method = "GET";
bncce36dca22015-04-21 22:11:235408 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105409 request.traffic_annotation =
5410 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275411
[email protected]d9da5fe2010-10-13 22:37:165412 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495413 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5414 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515415 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075416 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165418
bnc691fda62016-08-12 00:43:165419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165420
bncce36dca22015-04-21 22:11:235421 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415422 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235423 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5424 // fetch https://www.example.org/ via SPDY
5425 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415426 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495427 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415428 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155429 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415430 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155431 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415432 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025433 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415434 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5435 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025436 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415437 SpdySerializedFrame window_update_get_resp(
5438 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5439 SpdySerializedFrame window_update_body(
5440 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045441
5442 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415443 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5444 CreateMockWrite(window_update_get_resp, 6),
5445 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045446 };
5447
[email protected]d9da5fe2010-10-13 22:37:165448 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415449 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095450 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415451 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5452 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135453 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165454 };
5455
rch32320842015-05-16 15:57:095456 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5457 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075458 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165459
[email protected]8ddf8322012-02-23 18:08:065460 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365461 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065463 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365464 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165466
[email protected]49639fa2011-12-20 23:22:415467 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165468
bnc691fda62016-08-12 00:43:165469 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165471
rch32320842015-05-16 15:57:095472 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555473 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095474 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595475 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165476 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015477 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165478
[email protected]58e32bb2013-01-21 18:23:255479 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165480 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255481 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5482
bnc691fda62016-08-12 00:43:165483 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525484 ASSERT_TRUE(response);
5485 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025486 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165487
5488 std::string response_data;
bnc691fda62016-08-12 00:43:165489 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235490 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165491}
5492
5493// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015494TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275495 HttpRequestInfo request;
5496 request.method = "GET";
bncce36dca22015-04-21 22:11:235497 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105498 request.traffic_annotation =
5499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275500
[email protected]d9da5fe2010-10-13 22:37:165501 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495502 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5503 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515504 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075505 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165507
bnc691fda62016-08-12 00:43:165508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165509
bncce36dca22015-04-21 22:11:235510 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415511 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235512 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415513 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085514 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165515
5516 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415517 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165518 };
5519
bnc42331402016-07-25 13:36:155520 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415521 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165522 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415523 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165524 };
5525
rch8e6c6c42015-05-01 14:05:135526 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5527 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075528 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165529
[email protected]8ddf8322012-02-23 18:08:065530 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365531 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065533 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365534 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075535 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165536
[email protected]49639fa2011-12-20 23:22:415537 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165538
bnc691fda62016-08-12 00:43:165539 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165541
5542 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015543 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165544
ttuttle960fcbf2016-04-19 13:26:325545 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165546}
5547
[email protected]f6c63db52013-02-02 00:35:225548// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5549// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015550TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225551 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5552 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495553 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5554 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515555 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075556 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095557 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505558 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225559
5560 HttpRequestInfo request1;
5561 request1.method = "GET";
bncce36dca22015-04-21 22:11:235562 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225563 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105564 request1.traffic_annotation =
5565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225566
5567 HttpRequestInfo request2;
5568 request2.method = "GET";
bncce36dca22015-04-21 22:11:235569 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225570 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105571 request2.traffic_annotation =
5572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225573
bncce36dca22015-04-21 22:11:235574 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415575 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235576 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155577 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225578
bncce36dca22015-04-21 22:11:235579 // Fetch https://www.example.org/ via HTTP.
5580 const char get1[] =
5581 "GET / HTTP/1.1\r\n"
5582 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225583 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415584 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195585 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225586 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5587 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415588 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195589 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415590 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195591 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415592 SpdySerializedFrame window_update(
5593 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225594
bncce36dca22015-04-21 22:11:235595 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295596 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275597 connect2_block[kHttp2MethodHeader] = "CONNECT";
5598 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155599 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5600 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395601
bnc42331402016-07-25 13:36:155602 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225603
bncce36dca22015-04-21 22:11:235604 // Fetch https://mail.example.org/ via HTTP.
5605 const char get2[] =
5606 "GET / HTTP/1.1\r\n"
5607 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225608 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415609 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195610 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225611 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5612 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415613 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195614 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
bncdf80d44fd2016-07-15 20:27:415615 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195616 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225617
5618 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415619 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5620 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225621 };
5622
5623 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415624 CreateMockRead(conn_resp1, 1, ASYNC),
5625 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5626 CreateMockRead(wrapped_body1, 4, ASYNC),
5627 CreateMockRead(conn_resp2, 6, ASYNC),
5628 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5629 CreateMockRead(wrapped_body2, 9, ASYNC),
5630 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225631 };
5632
mmenke11eb5152015-06-09 14:50:505633 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5634 arraysize(spdy_writes));
5635 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225636
5637 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365638 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505639 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225640 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505641 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225642 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505643 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225644
5645 TestCompletionCallback callback;
5646
bnc691fda62016-08-12 00:43:165647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205648 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015649 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225650
5651 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165652 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225653 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5654
bnc691fda62016-08-12 00:43:165655 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525656 ASSERT_TRUE(response);
5657 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225658 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5659
5660 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295661 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165662 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505663 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225664
bnc691fda62016-08-12 00:43:165665 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205666 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015667 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225668
5669 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165670 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225671 // Even though the SPDY connection is reused, a new tunnelled connection has
5672 // to be created, so the socket's load timing looks like a fresh connection.
5673 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5674
5675 // The requests should have different IDs, since they each are using their own
5676 // separate stream.
5677 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5678
bnc691fda62016-08-12 00:43:165679 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505680 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225681}
5682
5683// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5684// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015685TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225686 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5687 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495688 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5689 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515690 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075691 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095692 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505693 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225694
5695 HttpRequestInfo request1;
5696 request1.method = "GET";
bncce36dca22015-04-21 22:11:235697 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225698 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105699 request1.traffic_annotation =
5700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225701
5702 HttpRequestInfo request2;
5703 request2.method = "GET";
bncce36dca22015-04-21 22:11:235704 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225705 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105706 request2.traffic_annotation =
5707 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225708
bncce36dca22015-04-21 22:11:235709 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415710 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235711 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155712 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225713
bncce36dca22015-04-21 22:11:235714 // Fetch https://www.example.org/ via HTTP.
5715 const char get1[] =
5716 "GET / HTTP/1.1\r\n"
5717 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225718 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415719 SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195720 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225721 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5722 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415723 SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195724 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
bncdf80d44fd2016-07-15 20:27:415725 SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195726 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
bncdf80d44fd2016-07-15 20:27:415727 SpdySerializedFrame window_update(
5728 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225729
bncce36dca22015-04-21 22:11:235730 // Fetch https://www.example.org/2 via HTTP.
5731 const char get2[] =
5732 "GET /2 HTTP/1.1\r\n"
5733 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225734 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415735 SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195736 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225737 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5738 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415739 SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195740 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
bncdf80d44fd2016-07-15 20:27:415741 SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195742 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225743
5744 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415745 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5746 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225747 };
5748
5749 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415750 CreateMockRead(conn_resp1, 1, ASYNC),
5751 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465752 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415753 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465754 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415755 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225756 };
5757
mmenke11eb5152015-06-09 14:50:505758 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5759 arraysize(spdy_writes));
5760 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225761
5762 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365763 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225765 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225767
5768 TestCompletionCallback callback;
5769
bnc87dcefc2017-05-25 12:47:585770 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195771 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205772 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225774
5775 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015776 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225777
5778 LoadTimingInfo load_timing_info;
5779 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5780 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5781
5782 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525783 ASSERT_TRUE(response);
5784 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225785 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5786
5787 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295788 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505789 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225790 trans.reset();
5791
bnc87dcefc2017-05-25 12:47:585792 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195793 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205794 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225796
[email protected]f6c63db52013-02-02 00:35:225797 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015798 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225799
5800 LoadTimingInfo load_timing_info2;
5801 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5802 TestLoadTimingReused(load_timing_info2);
5803
5804 // The requests should have the same ID.
5805 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5806
[email protected]90499482013-06-01 00:39:505807 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225808}
5809
5810// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5811// Proxy to different servers.
bncd16676a2016-07-20 16:23:015812TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225813 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495814 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5815 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515816 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075817 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095818 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505819 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225820
5821 HttpRequestInfo request1;
5822 request1.method = "GET";
bncce36dca22015-04-21 22:11:235823 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225824 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105825 request1.traffic_annotation =
5826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225827
5828 HttpRequestInfo request2;
5829 request2.method = "GET";
bncce36dca22015-04-21 22:11:235830 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225831 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105832 request2.traffic_annotation =
5833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225834
bncce36dca22015-04-21 22:11:235835 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265836 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235837 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415838 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155839 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5840 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Bence Békyd74f4382018-02-20 18:26:195841 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385842 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225843
bncce36dca22015-04-21 22:11:235844 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265845 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235846 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415847 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155848 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5849 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
Bence Békyd74f4382018-02-20 18:26:195850 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225851
5852 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415853 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225854 };
5855
5856 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415857 CreateMockRead(get_resp1, 1, ASYNC),
5858 CreateMockRead(body1, 2, ASYNC),
5859 CreateMockRead(get_resp2, 4, ASYNC),
5860 CreateMockRead(body2, 5, ASYNC),
5861 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225862 };
5863
mmenke11eb5152015-06-09 14:50:505864 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5865 arraysize(spdy_writes));
5866 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225867
5868 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365869 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225871
5872 TestCompletionCallback callback;
5873
bnc87dcefc2017-05-25 12:47:585874 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205876 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015877 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225878
5879 LoadTimingInfo load_timing_info;
5880 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5881 TestLoadTimingNotReused(load_timing_info,
5882 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5883
5884 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525885 ASSERT_TRUE(response);
5886 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025887 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225888
5889 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295890 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505891 rv = trans->Read(buf.get(), 256, callback.callback());
5892 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225893 // Delete the first request, so the second one can reuse the socket.
5894 trans.reset();
5895
bnc691fda62016-08-12 00:43:165896 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205897 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015898 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225899
5900 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165901 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225902 TestLoadTimingReused(load_timing_info2);
5903
5904 // The requests should have the same ID.
5905 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5906
bnc691fda62016-08-12 00:43:165907 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505908 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225909}
5910
[email protected]2df19bb2010-08-25 20:13:465911// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015912TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465913 HttpRequestInfo request;
5914 request.method = "GET";
bncce36dca22015-04-21 22:11:235915 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465916 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295917 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:105918 request.traffic_annotation =
5919 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465920
[email protected]79cb5c12011-09-12 13:12:045921 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495922 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5923 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515924 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075925 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095926 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275927
[email protected]2df19bb2010-08-25 20:13:465928 // Since we have proxy, should use full url
5929 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165930 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5931 "Host: www.example.org\r\n"
5932 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465933
bnc691fda62016-08-12 00:43:165934 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235935 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165936 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5937 "Host: www.example.org\r\n"
5938 "Proxy-Connection: keep-alive\r\n"
5939 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465940 };
5941
5942 // The proxy responds to the GET with a 407, using a persistent
5943 // connection.
5944 MockRead data_reads1[] = {
5945 // No credentials.
5946 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5947 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5948 MockRead("Proxy-Connection: keep-alive\r\n"),
5949 MockRead("Content-Length: 0\r\n\r\n"),
5950
5951 MockRead("HTTP/1.1 200 OK\r\n"),
5952 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5953 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065954 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465955 };
5956
5957 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5958 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075959 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065960 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075961 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465962
[email protected]49639fa2011-12-20 23:22:415963 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465964
bnc691fda62016-08-12 00:43:165965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505966
bnc691fda62016-08-12 00:43:165967 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465969
5970 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015971 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465972
[email protected]58e32bb2013-01-21 18:23:255973 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165974 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255975 TestLoadTimingNotReused(load_timing_info,
5976 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5977
bnc691fda62016-08-12 00:43:165978 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525979 ASSERT_TRUE(response);
5980 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465981 EXPECT_EQ(407, response->headers->response_code());
5982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435983 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465984
[email protected]49639fa2011-12-20 23:22:415985 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465986
bnc691fda62016-08-12 00:43:165987 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465989
5990 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015991 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465992
[email protected]58e32bb2013-01-21 18:23:255993 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165994 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255995 // Retrying with HTTP AUTH is considered to be reusing a socket.
5996 TestLoadTimingReused(load_timing_info);
5997
bnc691fda62016-08-12 00:43:165998 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525999 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466000
6001 EXPECT_TRUE(response->headers->IsKeepAlive());
6002 EXPECT_EQ(200, response->headers->response_code());
6003 EXPECT_EQ(100, response->headers->GetContentLength());
6004 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6005
6006 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526007 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466008}
6009
[email protected]23e482282013-06-14 16:08:026010void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086011 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426012 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086013 request.method = "GET";
bncce36dca22015-04-21 22:11:236014 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106015 request.traffic_annotation =
6016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086017
[email protected]cb9bf6ca2011-01-28 13:15:276018 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496019 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6020 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096021 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276022
[email protected]c744cf22009-02-27 07:28:086023 // Since we have proxy, should try to establish tunnel.
6024 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176025 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6026 "Host: www.example.org:443\r\n"
6027 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086028 };
6029
6030 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236031 status, MockRead("Content-Length: 10\r\n\r\n"),
6032 // No response body because the test stops reading here.
6033 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086034 };
6035
[email protected]31a2bfe2010-02-09 08:03:396036 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6037 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076038 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086039
[email protected]49639fa2011-12-20 23:22:416040 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086041
bnc691fda62016-08-12 00:43:166042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506043
tfarina42834112016-09-22 13:38:206044 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086046
6047 rv = callback.WaitForResult();
6048 EXPECT_EQ(expected_status, rv);
6049}
6050
[email protected]23e482282013-06-14 16:08:026051void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236052 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086053 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426054 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086055}
6056
bncd16676a2016-07-20 16:23:016057TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086058 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6059}
6060
bncd16676a2016-07-20 16:23:016061TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086062 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6063}
6064
bncd16676a2016-07-20 16:23:016065TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086066 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6067}
6068
bncd16676a2016-07-20 16:23:016069TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086070 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6071}
6072
bncd16676a2016-07-20 16:23:016073TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086074 ConnectStatusHelper(
6075 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6076}
6077
bncd16676a2016-07-20 16:23:016078TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086079 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6080}
6081
bncd16676a2016-07-20 16:23:016082TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086083 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6084}
6085
bncd16676a2016-07-20 16:23:016086TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086087 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6088}
6089
bncd16676a2016-07-20 16:23:016090TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086091 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6092}
6093
bncd16676a2016-07-20 16:23:016094TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086095 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6096}
6097
bncd16676a2016-07-20 16:23:016098TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086099 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6100}
6101
bncd16676a2016-07-20 16:23:016102TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086103 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6104}
6105
bncd16676a2016-07-20 16:23:016106TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086107 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6108}
6109
bncd16676a2016-07-20 16:23:016110TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086111 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6112}
6113
bncd16676a2016-07-20 16:23:016114TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086115 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6116}
6117
bncd16676a2016-07-20 16:23:016118TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086119 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6120}
6121
bncd16676a2016-07-20 16:23:016122TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376123 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6124}
6125
bncd16676a2016-07-20 16:23:016126TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086127 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6128}
6129
bncd16676a2016-07-20 16:23:016130TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086131 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6132}
6133
bncd16676a2016-07-20 16:23:016134TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086135 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6136}
6137
bncd16676a2016-07-20 16:23:016138TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086139 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6140}
6141
bncd16676a2016-07-20 16:23:016142TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086143 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6144}
6145
bncd16676a2016-07-20 16:23:016146TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086147 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6148}
6149
bncd16676a2016-07-20 16:23:016150TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086151 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6152}
6153
bncd16676a2016-07-20 16:23:016154TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086155 ConnectStatusHelperWithExpectedStatus(
6156 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546157 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086158}
6159
bncd16676a2016-07-20 16:23:016160TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086161 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6162}
6163
bncd16676a2016-07-20 16:23:016164TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086165 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6166}
6167
bncd16676a2016-07-20 16:23:016168TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086169 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6170}
6171
bncd16676a2016-07-20 16:23:016172TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086173 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6174}
6175
bncd16676a2016-07-20 16:23:016176TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086177 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6178}
6179
bncd16676a2016-07-20 16:23:016180TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086181 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6182}
6183
bncd16676a2016-07-20 16:23:016184TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086185 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6186}
6187
bncd16676a2016-07-20 16:23:016188TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086189 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6190}
6191
bncd16676a2016-07-20 16:23:016192TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086193 ConnectStatusHelper(
6194 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6195}
6196
bncd16676a2016-07-20 16:23:016197TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086198 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6199}
6200
bncd16676a2016-07-20 16:23:016201TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086202 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6203}
6204
bncd16676a2016-07-20 16:23:016205TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086206 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6207}
6208
bncd16676a2016-07-20 16:23:016209TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086210 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6211}
6212
bncd16676a2016-07-20 16:23:016213TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086214 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6215}
6216
bncd16676a2016-07-20 16:23:016217TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086218 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6219}
6220
bncd16676a2016-07-20 16:23:016221TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086222 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6223}
6224
[email protected]038e9a32008-10-08 22:40:166225// Test the flow when both the proxy server AND origin server require
6226// authentication. Again, this uses basic auth for both since that is
6227// the simplest to mock.
bncd16676a2016-07-20 16:23:016228TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276229 HttpRequestInfo request;
6230 request.method = "GET";
bncce36dca22015-04-21 22:11:236231 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106232 request.traffic_annotation =
6233 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276234
[email protected]038e9a32008-10-08 22:40:166235 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496236 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6237 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076239
bnc691fda62016-08-12 00:43:166240 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166241
[email protected]f9ee6b52008-11-08 06:46:236242 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236243 MockWrite(
6244 "GET http://www.example.org/ HTTP/1.1\r\n"
6245 "Host: www.example.org\r\n"
6246 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236247 };
6248
[email protected]038e9a32008-10-08 22:40:166249 MockRead data_reads1[] = {
6250 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6251 // Give a couple authenticate options (only the middle one is actually
6252 // supported).
[email protected]22927ad2009-09-21 19:56:196253 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166254 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6255 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6256 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6257 // Large content-length -- won't matter, as connection will be reset.
6258 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066259 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166260 };
6261
bnc691fda62016-08-12 00:43:166262 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166263 // request we should be issuing -- the final header line contains the
6264 // proxy's credentials.
6265 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236266 MockWrite(
6267 "GET http://www.example.org/ HTTP/1.1\r\n"
6268 "Host: www.example.org\r\n"
6269 "Proxy-Connection: keep-alive\r\n"
6270 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166271 };
6272
6273 // Now the proxy server lets the request pass through to origin server.
6274 // The origin server responds with a 401.
6275 MockRead data_reads2[] = {
6276 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6277 // Note: We are using the same realm-name as the proxy server. This is
6278 // completely valid, as realms are unique across hosts.
6279 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6280 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6281 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066282 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166283 };
6284
bnc691fda62016-08-12 00:43:166285 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166286 // the credentials for both the proxy and origin server.
6287 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236288 MockWrite(
6289 "GET http://www.example.org/ HTTP/1.1\r\n"
6290 "Host: www.example.org\r\n"
6291 "Proxy-Connection: keep-alive\r\n"
6292 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6293 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166294 };
6295
6296 // Lastly we get the desired content.
6297 MockRead data_reads3[] = {
6298 MockRead("HTTP/1.0 200 OK\r\n"),
6299 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6300 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066301 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166302 };
6303
[email protected]31a2bfe2010-02-09 08:03:396304 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6305 data_writes1, arraysize(data_writes1));
6306 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6307 data_writes2, arraysize(data_writes2));
6308 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6309 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6312 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166313
[email protected]49639fa2011-12-20 23:22:416314 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166315
tfarina42834112016-09-22 13:38:206316 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166318
6319 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016320 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166321
bnc691fda62016-08-12 00:43:166322 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526323 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046324 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166325
[email protected]49639fa2011-12-20 23:22:416326 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166327
bnc691fda62016-08-12 00:43:166328 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166330
6331 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016332 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166333
bnc691fda62016-08-12 00:43:166334 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526335 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046336 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166337
[email protected]49639fa2011-12-20 23:22:416338 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166339
bnc691fda62016-08-12 00:43:166340 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6341 callback3.callback());
robpercival214763f2016-07-01 23:27:016342 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166343
6344 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016345 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166346
bnc691fda62016-08-12 00:43:166347 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526348 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166349 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166350}
[email protected]4ddaf2502008-10-23 18:26:196351
[email protected]ea9dc9a2009-09-05 00:43:326352// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6353// can't hook into its internals to cause it to generate predictable NTLM
6354// authorization headers.
6355#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376356// The NTLM authentication unit tests are based on known test data from the
6357// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6358// flow rather than the implementation of the NTLM protocol. See net/ntlm
6359// for the implementation and testing of the protocol.
6360//
6361// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296362
6363// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556364TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426365 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246366 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556367 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106368 request.traffic_annotation =
6369 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546370
6371 // Ensure load is not disrupted by flags which suppress behaviour specific
6372 // to other auth schemes.
6373 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246374
Zentaro Kavanagh6ccee512017-09-28 18:34:096375 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6376 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276378
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376379 // Generate the NTLM messages based on known test data.
6380 std::string negotiate_msg;
6381 std::string challenge_msg;
6382 std::string authenticate_msg;
6383 base::Base64Encode(
6384 base::StringPiece(
6385 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6386 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6387 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556388 base::Base64Encode(
6389 base::StringPiece(
6390 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6391 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6392 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376393 base::Base64Encode(
6394 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096395 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556396 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6397 arraysize(
6398 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376399 &authenticate_msg);
6400
[email protected]3f918782009-02-28 01:29:246401 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556402 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6403 "Host: server\r\n"
6404 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246405 };
6406
6407 MockRead data_reads1[] = {
6408 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046409 // Negotiate and NTLM are often requested together. However, we only want
6410 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6411 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246412 MockRead("WWW-Authenticate: NTLM\r\n"),
6413 MockRead("Connection: close\r\n"),
6414 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366415 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246416 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246417 };
6418
6419 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166420 // After restarting with a null identity, this is the
6421 // request we should be issuing -- the final header line contains a Type
6422 // 1 message.
6423 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556424 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166425 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376426 "Authorization: NTLM "),
6427 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246428
bnc691fda62016-08-12 00:43:166429 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376430 // (using correct credentials). The second request continues on the
6431 // same connection.
bnc691fda62016-08-12 00:43:166432 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556433 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166434 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376435 "Authorization: NTLM "),
6436 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246437 };
6438
6439 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026440 // The origin server responds with a Type 2 message.
6441 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376442 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6443 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026444 MockRead("Content-Type: text/html\r\n\r\n"),
6445 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246446
Bence Béky1e4ef192017-09-18 19:58:026447 // Lastly we get the desired content.
6448 MockRead("HTTP/1.1 200 OK\r\n"),
6449 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6450 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246451 };
6452
[email protected]31a2bfe2010-02-09 08:03:396453 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6454 data_writes1, arraysize(data_writes1));
6455 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6456 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076457 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6458 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246459
Bence Béky83eb3512017-09-05 12:56:096460 SSLSocketDataProvider ssl1(ASYNC, OK);
6461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6462 SSLSocketDataProvider ssl2(ASYNC, OK);
6463 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6464
[email protected]49639fa2011-12-20 23:22:416465 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246466
bnc691fda62016-08-12 00:43:166467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506468
tfarina42834112016-09-22 13:38:206469 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246471
6472 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016473 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246474
bnc691fda62016-08-12 00:43:166475 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226476
bnc691fda62016-08-12 00:43:166477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526478 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046479 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246480
[email protected]49639fa2011-12-20 23:22:416481 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256482
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376483 rv = trans.RestartWithAuth(
6484 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6485 callback2.callback());
robpercival214763f2016-07-01 23:27:016486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256487
6488 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016489 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256490
bnc691fda62016-08-12 00:43:166491 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256492
bnc691fda62016-08-12 00:43:166493 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526494 ASSERT_TRUE(response);
6495 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256496
[email protected]49639fa2011-12-20 23:22:416497 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246498
bnc691fda62016-08-12 00:43:166499 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246501
[email protected]0757e7702009-03-27 04:00:226502 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016503 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246504
bnc691fda62016-08-12 00:43:166505 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526506 ASSERT_TRUE(response);
6507 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026508 EXPECT_EQ(14, response->headers->GetContentLength());
6509
6510 std::string response_data;
6511 rv = ReadTransaction(&trans, &response_data);
6512 EXPECT_THAT(rv, IsOk());
6513 EXPECT_EQ("Please Login\r\n", response_data);
6514
6515 EXPECT_TRUE(data1.AllReadDataConsumed());
6516 EXPECT_TRUE(data1.AllWriteDataConsumed());
6517 EXPECT_TRUE(data2.AllReadDataConsumed());
6518 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246519}
6520
[email protected]385a4672009-03-11 22:21:296521// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556522TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426523 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296524 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556525 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106526 request.traffic_annotation =
6527 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296528
Zentaro Kavanagh6ccee512017-09-28 18:34:096529 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6530 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276532
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376533 // Generate the NTLM messages based on known test data.
6534 std::string negotiate_msg;
6535 std::string challenge_msg;
6536 std::string authenticate_msg;
6537 base::Base64Encode(
6538 base::StringPiece(
6539 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6540 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6541 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556542 base::Base64Encode(
6543 base::StringPiece(
6544 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6545 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6546 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376547 base::Base64Encode(
6548 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096549 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556550 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6551 arraysize(
6552 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376553 &authenticate_msg);
6554
6555 // The authenticate message when |kWrongPassword| is sent.
6556 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556557 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6558 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6559 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6560 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6561 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6562 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376563
Zentaro Kavanagh1890a3d2018-01-29 19:52:556564 // Sanity check that it's the same length as the correct authenticate message
6565 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376566 ASSERT_EQ(authenticate_msg.length(),
6567 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556568 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376569
[email protected]385a4672009-03-11 22:21:296570 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556571 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6572 "Host: server\r\n"
6573 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296574 };
6575
6576 MockRead data_reads1[] = {
6577 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046578 // Negotiate and NTLM are often requested together. However, we only want
6579 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6580 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296581 MockRead("WWW-Authenticate: NTLM\r\n"),
6582 MockRead("Connection: close\r\n"),
6583 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366584 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296585 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296586 };
6587
6588 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166589 // After restarting with a null identity, this is the
6590 // request we should be issuing -- the final header line contains a Type
6591 // 1 message.
6592 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556593 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166594 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376595 "Authorization: NTLM "),
6596 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296597
bnc691fda62016-08-12 00:43:166598 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376599 // (using incorrect credentials). The second request continues on the
6600 // same connection.
bnc691fda62016-08-12 00:43:166601 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556602 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166603 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376604 "Authorization: NTLM "),
6605 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296606 };
6607
6608 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376609 // The origin server responds with a Type 2 message.
6610 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6611 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6612 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6613 MockRead("Content-Type: text/html\r\n\r\n"),
6614 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296615
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376616 // Wrong password.
6617 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6618 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6619 MockRead("Content-Length: 42\r\n"),
6620 MockRead("Content-Type: text/html\r\n\r\n"),
6621 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296622 };
6623
6624 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166625 // After restarting with a null identity, this is the
6626 // request we should be issuing -- the final header line contains a Type
6627 // 1 message.
6628 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556629 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166630 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376631 "Authorization: NTLM "),
6632 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296633
bnc691fda62016-08-12 00:43:166634 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6635 // (the credentials for the origin server). The second request continues
6636 // on the same connection.
6637 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556638 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166639 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376640 "Authorization: NTLM "),
6641 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296642 };
6643
6644 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026645 // The origin server responds with a Type 2 message.
6646 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376647 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6648 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026649 MockRead("Content-Type: text/html\r\n\r\n"),
6650 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296651
Bence Béky1e4ef192017-09-18 19:58:026652 // Lastly we get the desired content.
6653 MockRead("HTTP/1.1 200 OK\r\n"),
6654 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6655 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296656 };
6657
[email protected]31a2bfe2010-02-09 08:03:396658 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6659 data_writes1, arraysize(data_writes1));
6660 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6661 data_writes2, arraysize(data_writes2));
6662 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6663 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6665 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6666 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296667
Bence Béky83eb3512017-09-05 12:56:096668 SSLSocketDataProvider ssl1(ASYNC, OK);
6669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6670 SSLSocketDataProvider ssl2(ASYNC, OK);
6671 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6672 SSLSocketDataProvider ssl3(ASYNC, OK);
6673 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6674
[email protected]49639fa2011-12-20 23:22:416675 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296676
bnc691fda62016-08-12 00:43:166677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506678
tfarina42834112016-09-22 13:38:206679 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296681
6682 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016683 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296684
bnc691fda62016-08-12 00:43:166685 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296686
bnc691fda62016-08-12 00:43:166687 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526688 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046689 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296690
[email protected]49639fa2011-12-20 23:22:416691 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296692
[email protected]0757e7702009-03-27 04:00:226693 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376694 rv = trans.RestartWithAuth(
6695 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6696 callback2.callback());
robpercival214763f2016-07-01 23:27:016697 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296698
[email protected]10af5fe72011-01-31 16:17:256699 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016700 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296701
bnc691fda62016-08-12 00:43:166702 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416703 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166704 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256706 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016707 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166708 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226709
bnc691fda62016-08-12 00:43:166710 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526711 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046712 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226713
[email protected]49639fa2011-12-20 23:22:416714 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226715
6716 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376717 rv = trans.RestartWithAuth(
6718 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6719 callback4.callback());
robpercival214763f2016-07-01 23:27:016720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256721
6722 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016723 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256724
bnc691fda62016-08-12 00:43:166725 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256726
[email protected]49639fa2011-12-20 23:22:416727 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256728
6729 // One more roundtrip
bnc691fda62016-08-12 00:43:166730 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226732
6733 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016734 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226735
bnc691fda62016-08-12 00:43:166736 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526737 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026738 EXPECT_EQ(14, response->headers->GetContentLength());
6739
6740 std::string response_data;
6741 rv = ReadTransaction(&trans, &response_data);
6742 EXPECT_THAT(rv, IsOk());
6743 EXPECT_EQ("Please Login\r\n", response_data);
6744
6745 EXPECT_TRUE(data1.AllReadDataConsumed());
6746 EXPECT_TRUE(data1.AllWriteDataConsumed());
6747 EXPECT_TRUE(data2.AllReadDataConsumed());
6748 EXPECT_TRUE(data2.AllWriteDataConsumed());
6749 EXPECT_TRUE(data3.AllReadDataConsumed());
6750 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296751}
Bence Béky83eb3512017-09-05 12:56:096752
Bence Béky3238f2e12017-09-22 22:44:496753// Server requests NTLM authentication, which is not supported over HTTP/2.
6754// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096755TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096756 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6757 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096758
Zentaro Kavanagh1890a3d2018-01-29 19:52:556759 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096760
6761 HttpRequestInfo request;
6762 request.method = "GET";
6763 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:106764 request.traffic_annotation =
6765 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096766
6767 // First request without credentials.
6768 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6769 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6770 1, std::move(request_headers0), LOWEST, true));
6771
6772 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276773 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096774 response_headers0["www-authenticate"] = "NTLM";
6775 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6776 1, std::move(response_headers0), true));
6777
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376778 // Stream 1 is closed.
6779 spdy_util_.UpdateWithStreamDestruction(1);
6780
6781 // Generate the NTLM messages based on known test data.
6782 std::string negotiate_msg;
6783 std::string challenge_msg;
6784 std::string authenticate_msg;
6785 base::Base64Encode(
6786 base::StringPiece(
6787 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6788 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6789 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556790 base::Base64Encode(
6791 base::StringPiece(
6792 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6793 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6794 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376795 base::Base64Encode(
6796 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096797 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556798 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6799 arraysize(
6800 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376801 &authenticate_msg);
6802
6803 // Retry with authorization header.
6804 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6805 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6806 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6807 3, std::move(request_headers1), LOWEST, true));
6808
6809 SpdySerializedFrame rst(
6810 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6811
Bence Béky3238f2e12017-09-22 22:44:496812 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6813 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096814
6815 // Retry yet again using HTTP/1.1.
6816 MockWrite writes1[] = {
6817 // After restarting with a null identity, this is the
6818 // request we should be issuing -- the final header line contains a Type
6819 // 1 message.
6820 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556821 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096822 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376823 "Authorization: NTLM "),
6824 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096825
6826 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6827 // (the credentials for the origin server). The second request continues
6828 // on the same connection.
6829 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556830 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096831 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376832 "Authorization: NTLM "),
6833 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096834 };
6835
6836 MockRead reads1[] = {
6837 // The origin server responds with a Type 2 message.
6838 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376839 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6840 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096841 MockRead("Content-Type: text/html\r\n\r\n"),
6842 MockRead("You are not authorized to view this page\r\n"),
6843
6844 // Lastly we get the desired content.
6845 MockRead("HTTP/1.1 200 OK\r\n"),
6846 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026847 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096848 };
6849 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6850 arraysize(writes0));
6851 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6852 arraysize(writes1));
6853 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6855
6856 SSLSocketDataProvider ssl0(ASYNC, OK);
6857 ssl0.next_proto = kProtoHTTP2;
6858 SSLSocketDataProvider ssl1(ASYNC, OK);
6859 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6861
6862 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6864
6865 TestCompletionCallback callback1;
6866 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6868
6869 rv = callback1.WaitForResult();
6870 EXPECT_THAT(rv, IsOk());
6871
6872 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6873
6874 const HttpResponseInfo* response = trans.GetResponseInfo();
6875 ASSERT_TRUE(response);
6876 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6877
6878 TestCompletionCallback callback2;
6879
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376880 rv = trans.RestartWithAuth(
6881 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6882 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6884
6885 rv = callback2.WaitForResult();
6886 EXPECT_THAT(rv, IsOk());
6887
6888 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6889
6890 response = trans.GetResponseInfo();
6891 ASSERT_TRUE(response);
6892 EXPECT_FALSE(response->auth_challenge);
6893
6894 TestCompletionCallback callback3;
6895
6896 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6898
6899 rv = callback3.WaitForResult();
6900 EXPECT_THAT(rv, IsOk());
6901
6902 response = trans.GetResponseInfo();
6903 ASSERT_TRUE(response);
6904 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026905 EXPECT_EQ(14, response->headers->GetContentLength());
6906
6907 std::string response_data;
6908 rv = ReadTransaction(&trans, &response_data);
6909 EXPECT_THAT(rv, IsOk());
6910 EXPECT_EQ("Please Login\r\n", response_data);
6911
6912 EXPECT_TRUE(data0.AllReadDataConsumed());
6913 EXPECT_TRUE(data0.AllWriteDataConsumed());
6914 EXPECT_TRUE(data1.AllReadDataConsumed());
6915 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096916}
[email protected]ea9dc9a2009-09-05 00:43:326917#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296918
[email protected]4ddaf2502008-10-23 18:26:196919// Test reading a server response which has only headers, and no body.
6920// After some maximum number of bytes is consumed, the transaction should
6921// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426923 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196924 request.method = "GET";
bncce36dca22015-04-21 22:11:236925 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106926 request.traffic_annotation =
6927 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196928
danakj1fd259a02016-04-16 03:17:096929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166930 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276931
[email protected]b75b7b2f2009-10-06 00:54:536932 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436933 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536934 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196935
6936 MockRead data_reads[] = {
6937 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066938 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196939 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066940 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196941 };
[email protected]31a2bfe2010-02-09 08:03:396942 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076943 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196944
[email protected]49639fa2011-12-20 23:22:416945 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196946
tfarina42834112016-09-22 13:38:206947 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196949
6950 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016951 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196952}
[email protected]f4e426b2008-11-05 00:24:496953
6954// Make sure that we don't try to reuse a TCPClientSocket when failing to
6955// establish tunnel.
6956// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016957TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276958 HttpRequestInfo request;
6959 request.method = "GET";
bncce36dca22015-04-21 22:11:236960 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106961 request.traffic_annotation =
6962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276963
[email protected]f4e426b2008-11-05 00:24:496964 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496965 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6966 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:016967
danakj1fd259a02016-04-16 03:17:096968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496969
bnc87dcefc2017-05-25 12:47:586970 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196971 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496972
[email protected]f4e426b2008-11-05 00:24:496973 // Since we have proxy, should try to establish tunnel.
6974 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176975 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6976 "Host: www.example.org:443\r\n"
6977 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496978 };
6979
[email protected]77848d12008-11-14 00:00:226980 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496981 // connection. Usually a proxy would return 501 (not implemented),
6982 // or 200 (tunnel established).
6983 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236984 MockRead("HTTP/1.1 404 Not Found\r\n"),
6985 MockRead("Content-Length: 10\r\n\r\n"),
6986 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496987 };
6988
[email protected]31a2bfe2010-02-09 08:03:396989 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6990 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076991 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496992
[email protected]49639fa2011-12-20 23:22:416993 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496994
tfarina42834112016-09-22 13:38:206995 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496997
6998 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016999 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497000
[email protected]b4404c02009-04-10 16:38:527001 // Empty the current queue. This is necessary because idle sockets are
7002 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557003 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527004
[email protected]f4e426b2008-11-05 00:24:497005 // We now check to make sure the TCPClientSocket was not added back to
7006 // the pool.
[email protected]90499482013-06-01 00:39:507007 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497008 trans.reset();
fdoray92e35a72016-06-10 15:54:557009 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497010 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507011 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497012}
[email protected]372d34a2008-11-05 21:30:517013
[email protected]1b157c02009-04-21 01:55:407014// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017015TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427016 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407017 request.method = "GET";
bncce36dca22015-04-21 22:11:237018 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107019 request.traffic_annotation =
7020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407021
danakj1fd259a02016-04-16 03:17:097022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277023
bnc691fda62016-08-12 00:43:167024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277025
[email protected]1b157c02009-04-21 01:55:407026 MockRead data_reads[] = {
7027 // A part of the response body is received with the response headers.
7028 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7029 // The rest of the response body is received in two parts.
7030 MockRead("lo"),
7031 MockRead(" world"),
7032 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067033 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407034 };
7035
[email protected]31a2bfe2010-02-09 08:03:397036 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077037 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407038
[email protected]49639fa2011-12-20 23:22:417039 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407040
tfarina42834112016-09-22 13:38:207041 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407043
7044 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017045 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407046
bnc691fda62016-08-12 00:43:167047 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527048 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407049
wezca1070932016-05-26 20:30:527050 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407051 std::string status_line = response->headers->GetStatusLine();
7052 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7053
[email protected]90499482013-06-01 00:39:507054 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407055
7056 std::string response_data;
bnc691fda62016-08-12 00:43:167057 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017058 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407059 EXPECT_EQ("hello world", response_data);
7060
7061 // Empty the current queue. This is necessary because idle sockets are
7062 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557063 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407064
7065 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507066 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407067}
7068
[email protected]76a505b2010-08-25 06:23:007069// Make sure that we recycle a SSL socket after reading all of the response
7070// body.
bncd16676a2016-07-20 16:23:017071TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007072 HttpRequestInfo request;
7073 request.method = "GET";
bncce36dca22015-04-21 22:11:237074 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107075 request.traffic_annotation =
7076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007077
7078 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237079 MockWrite(
7080 "GET / HTTP/1.1\r\n"
7081 "Host: www.example.org\r\n"
7082 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007083 };
7084
7085 MockRead data_reads[] = {
7086 MockRead("HTTP/1.1 200 OK\r\n"),
7087 MockRead("Content-Length: 11\r\n\r\n"),
7088 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067089 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007090 };
7091
[email protected]8ddf8322012-02-23 18:08:067092 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007094
7095 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7096 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077097 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007098
[email protected]49639fa2011-12-20 23:22:417099 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007100
danakj1fd259a02016-04-16 03:17:097101 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007103
tfarina42834112016-09-22 13:38:207104 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007105
robpercival214763f2016-07-01 23:27:017106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7107 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007108
bnc691fda62016-08-12 00:43:167109 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527110 ASSERT_TRUE(response);
7111 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007112 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7113
[email protected]90499482013-06-01 00:39:507114 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007115
7116 std::string response_data;
bnc691fda62016-08-12 00:43:167117 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017118 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007119 EXPECT_EQ("hello world", response_data);
7120
7121 // Empty the current queue. This is necessary because idle sockets are
7122 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557123 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007124
7125 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507126 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007127}
7128
7129// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7130// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017131TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007132 HttpRequestInfo request;
7133 request.method = "GET";
bncce36dca22015-04-21 22:11:237134 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107135 request.traffic_annotation =
7136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007137
7138 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237139 MockWrite(
7140 "GET / HTTP/1.1\r\n"
7141 "Host: www.example.org\r\n"
7142 "Connection: keep-alive\r\n\r\n"),
7143 MockWrite(
7144 "GET / HTTP/1.1\r\n"
7145 "Host: www.example.org\r\n"
7146 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007147 };
7148
7149 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427150 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7151 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007152
[email protected]8ddf8322012-02-23 18:08:067153 SSLSocketDataProvider ssl(ASYNC, OK);
7154 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7156 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007157
7158 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7159 data_writes, arraysize(data_writes));
7160 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7161 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077162 session_deps_.socket_factory->AddSocketDataProvider(&data);
7163 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007164
[email protected]49639fa2011-12-20 23:22:417165 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007166
danakj1fd259a02016-04-16 03:17:097167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587168 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197169 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007170
tfarina42834112016-09-22 13:38:207171 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007172
robpercival214763f2016-07-01 23:27:017173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7174 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007175
7176 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527177 ASSERT_TRUE(response);
7178 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007179 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7180
[email protected]90499482013-06-01 00:39:507181 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007182
7183 std::string response_data;
7184 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017185 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007186 EXPECT_EQ("hello world", response_data);
7187
7188 // Empty the current queue. This is necessary because idle sockets are
7189 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557190 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007191
7192 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507193 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007194
7195 // Now start the second transaction, which should reuse the previous socket.
7196
bnc87dcefc2017-05-25 12:47:587197 trans =
Jeremy Roman0579ed62017-08-29 15:56:197198 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007199
tfarina42834112016-09-22 13:38:207200 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007201
robpercival214763f2016-07-01 23:27:017202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7203 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007204
7205 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527206 ASSERT_TRUE(response);
7207 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007208 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7209
[email protected]90499482013-06-01 00:39:507210 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007211
7212 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017213 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007214 EXPECT_EQ("hello world", response_data);
7215
7216 // Empty the current queue. This is necessary because idle sockets are
7217 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557218 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007219
7220 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507221 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007222}
7223
maksim.sisov0adf8592016-07-15 06:25:567224// Grab a socket, use it, and put it back into the pool. Then, make
7225// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017226TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567227 HttpRequestInfo request;
7228 request.method = "GET";
7229 request.url = GURL("http://www.example.org/");
7230 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107231 request.traffic_annotation =
7232 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567233
7234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7235
bnc691fda62016-08-12 00:43:167236 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567237
7238 MockRead data_reads[] = {
7239 // A part of the response body is received with the response headers.
7240 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7241 // The rest of the response body is received in two parts.
7242 MockRead("lo"), MockRead(" world"),
7243 MockRead("junk"), // Should not be read!!
7244 MockRead(SYNCHRONOUS, OK),
7245 };
7246
7247 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7248 session_deps_.socket_factory->AddSocketDataProvider(&data);
7249
7250 TestCompletionCallback callback;
7251
tfarina42834112016-09-22 13:38:207252 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7254
7255 EXPECT_THAT(callback.GetResult(rv), IsOk());
7256
bnc691fda62016-08-12 00:43:167257 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567258 ASSERT_TRUE(response);
7259 EXPECT_TRUE(response->headers);
7260 std::string status_line = response->headers->GetStatusLine();
7261 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7262
7263 // Make memory critical notification and ensure the transaction still has been
7264 // operating right.
7265 base::MemoryPressureListener::NotifyMemoryPressure(
7266 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7267 base::RunLoop().RunUntilIdle();
7268
7269 // Socket should not be flushed as long as it is not idle.
7270 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7271
7272 std::string response_data;
bnc691fda62016-08-12 00:43:167273 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567274 EXPECT_THAT(rv, IsOk());
7275 EXPECT_EQ("hello world", response_data);
7276
7277 // Empty the current queue. This is necessary because idle sockets are
7278 // added to the connection pool asynchronously with a PostTask.
7279 base::RunLoop().RunUntilIdle();
7280
7281 // We now check to make sure the socket was added back to the pool.
7282 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7283
7284 // Idle sockets should be flushed now.
7285 base::MemoryPressureListener::NotifyMemoryPressure(
7286 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7287 base::RunLoop().RunUntilIdle();
7288
7289 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7290}
7291
yucliu48f235d2018-01-11 00:59:557292// Disable idle socket closing on memory pressure.
7293// Grab a socket, use it, and put it back into the pool. Then, make
7294// low memory notification and ensure the socket pool is NOT flushed.
7295TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7296 HttpRequestInfo request;
7297 request.method = "GET";
7298 request.url = GURL("http://www.example.org/");
7299 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107300 request.traffic_annotation =
7301 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557302
7303 // Disable idle socket closing on memory pressure.
7304 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7306
7307 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7308
7309 MockRead data_reads[] = {
7310 // A part of the response body is received with the response headers.
7311 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7312 // The rest of the response body is received in two parts.
7313 MockRead("lo"), MockRead(" world"),
7314 MockRead("junk"), // Should not be read!!
7315 MockRead(SYNCHRONOUS, OK),
7316 };
7317
7318 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7319 session_deps_.socket_factory->AddSocketDataProvider(&data);
7320
7321 TestCompletionCallback callback;
7322
7323 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7325
7326 EXPECT_THAT(callback.GetResult(rv), IsOk());
7327
7328 const HttpResponseInfo* response = trans.GetResponseInfo();
7329 ASSERT_TRUE(response);
7330 EXPECT_TRUE(response->headers);
7331 std::string status_line = response->headers->GetStatusLine();
7332 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7333
7334 // Make memory critical notification and ensure the transaction still has been
7335 // operating right.
7336 base::MemoryPressureListener::NotifyMemoryPressure(
7337 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7338 base::RunLoop().RunUntilIdle();
7339
7340 // Socket should not be flushed as long as it is not idle.
7341 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7342
7343 std::string response_data;
7344 rv = ReadTransaction(&trans, &response_data);
7345 EXPECT_THAT(rv, IsOk());
7346 EXPECT_EQ("hello world", response_data);
7347
7348 // Empty the current queue. This is necessary because idle sockets are
7349 // added to the connection pool asynchronously with a PostTask.
7350 base::RunLoop().RunUntilIdle();
7351
7352 // We now check to make sure the socket was added back to the pool.
7353 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7354
7355 // Idle sockets should NOT be flushed on moderate memory pressure.
7356 base::MemoryPressureListener::NotifyMemoryPressure(
7357 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7358 base::RunLoop().RunUntilIdle();
7359
7360 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7361
7362 // Idle sockets should NOT be flushed on critical memory pressure.
7363 base::MemoryPressureListener::NotifyMemoryPressure(
7364 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7365 base::RunLoop().RunUntilIdle();
7366
7367 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7368}
7369
maksim.sisov0adf8592016-07-15 06:25:567370// Grab an SSL socket, use it, and put it back into the pool. Then, make
7371// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017372TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567373 HttpRequestInfo request;
7374 request.method = "GET";
7375 request.url = GURL("https://www.example.org/");
7376 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107377 request.traffic_annotation =
7378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567379
7380 MockWrite data_writes[] = {
7381 MockWrite("GET / HTTP/1.1\r\n"
7382 "Host: www.example.org\r\n"
7383 "Connection: keep-alive\r\n\r\n"),
7384 };
7385
7386 MockRead data_reads[] = {
7387 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7388 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7389
7390 SSLSocketDataProvider ssl(ASYNC, OK);
7391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7392
7393 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7394 arraysize(data_writes));
7395 session_deps_.socket_factory->AddSocketDataProvider(&data);
7396
7397 TestCompletionCallback callback;
7398
7399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567401
7402 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207403 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567404
7405 EXPECT_THAT(callback.GetResult(rv), IsOk());
7406
bnc691fda62016-08-12 00:43:167407 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567408 ASSERT_TRUE(response);
7409 ASSERT_TRUE(response->headers);
7410 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7411
7412 // Make memory critical notification and ensure the transaction still has been
7413 // operating right.
7414 base::MemoryPressureListener::NotifyMemoryPressure(
7415 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7416 base::RunLoop().RunUntilIdle();
7417
7418 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7419
7420 std::string response_data;
bnc691fda62016-08-12 00:43:167421 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567422 EXPECT_THAT(rv, IsOk());
7423 EXPECT_EQ("hello world", response_data);
7424
7425 // Empty the current queue. This is necessary because idle sockets are
7426 // added to the connection pool asynchronously with a PostTask.
7427 base::RunLoop().RunUntilIdle();
7428
7429 // We now check to make sure the socket was added back to the pool.
7430 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7431
7432 // Make memory notification once again and ensure idle socket is closed.
7433 base::MemoryPressureListener::NotifyMemoryPressure(
7434 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7435 base::RunLoop().RunUntilIdle();
7436
7437 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7438}
7439
[email protected]b4404c02009-04-10 16:38:527440// Make sure that we recycle a socket after a zero-length response.
7441// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017442TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427443 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527444 request.method = "GET";
bncce36dca22015-04-21 22:11:237445 request.url = GURL(
7446 "http://www.example.org/csi?v=3&s=web&action=&"
7447 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7448 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7449 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:107450 request.traffic_annotation =
7451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527452
danakj1fd259a02016-04-16 03:17:097453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277454
[email protected]b4404c02009-04-10 16:38:527455 MockRead data_reads[] = {
7456 MockRead("HTTP/1.1 204 No Content\r\n"
7457 "Content-Length: 0\r\n"
7458 "Content-Type: text/html\r\n\r\n"),
7459 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067460 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527461 };
7462
[email protected]31a2bfe2010-02-09 08:03:397463 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077464 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527465
mmenkecc2298e2015-12-07 18:20:187466 // Transaction must be created after the MockReads, so it's destroyed before
7467 // them.
bnc691fda62016-08-12 00:43:167468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187469
[email protected]49639fa2011-12-20 23:22:417470 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527471
tfarina42834112016-09-22 13:38:207472 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527474
7475 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017476 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527477
bnc691fda62016-08-12 00:43:167478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527479 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527480
wezca1070932016-05-26 20:30:527481 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527482 std::string status_line = response->headers->GetStatusLine();
7483 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7484
[email protected]90499482013-06-01 00:39:507485 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527486
7487 std::string response_data;
bnc691fda62016-08-12 00:43:167488 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017489 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527490 EXPECT_EQ("", response_data);
7491
7492 // Empty the current queue. This is necessary because idle sockets are
7493 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557494 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527495
7496 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507497 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527498}
7499
bncd16676a2016-07-20 16:23:017500TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097501 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227502 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197503 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227504 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277505
[email protected]1c773ea12009-04-28 19:58:427506 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517507 // Transaction 1: a GET request that succeeds. The socket is recycled
7508 // after use.
7509 request[0].method = "GET";
7510 request[0].url = GURL("http://www.google.com/");
7511 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107512 request[0].traffic_annotation =
7513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517514 // Transaction 2: a POST request. Reuses the socket kept alive from
7515 // transaction 1. The first attempts fails when writing the POST data.
7516 // This causes the transaction to retry with a new socket. The second
7517 // attempt succeeds.
7518 request[1].method = "POST";
7519 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277520 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517521 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107522 request[1].traffic_annotation =
7523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517524
danakj1fd259a02016-04-16 03:17:097525 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517526
7527 // The first socket is used for transaction 1 and the first attempt of
7528 // transaction 2.
7529
7530 // The response of transaction 1.
7531 MockRead data_reads1[] = {
7532 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7533 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067534 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517535 };
7536 // The mock write results of transaction 1 and the first attempt of
7537 // transaction 2.
7538 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067539 MockWrite(SYNCHRONOUS, 64), // GET
7540 MockWrite(SYNCHRONOUS, 93), // POST
7541 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517542 };
[email protected]31a2bfe2010-02-09 08:03:397543 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7544 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517545
7546 // The second socket is used for the second attempt of transaction 2.
7547
7548 // The response of transaction 2.
7549 MockRead data_reads2[] = {
7550 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7551 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067552 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517553 };
7554 // The mock write results of the second attempt of transaction 2.
7555 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067556 MockWrite(SYNCHRONOUS, 93), // POST
7557 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517558 };
[email protected]31a2bfe2010-02-09 08:03:397559 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7560 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517561
[email protected]bb88e1d32013-05-03 23:11:077562 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7563 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517564
thestig9d3bb0c2015-01-24 00:49:517565 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517566 "hello world", "welcome"
7567 };
7568
7569 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517571
[email protected]49639fa2011-12-20 23:22:417572 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517573
tfarina42834112016-09-22 13:38:207574 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517576
7577 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017578 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517579
bnc691fda62016-08-12 00:43:167580 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527581 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517582
wezca1070932016-05-26 20:30:527583 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517584 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7585
7586 std::string response_data;
bnc691fda62016-08-12 00:43:167587 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017588 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517589 EXPECT_EQ(kExpectedResponseData[i], response_data);
7590 }
7591}
[email protected]f9ee6b52008-11-08 06:46:237592
7593// Test the request-challenge-retry sequence for basic auth when there is
7594// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167595// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017596TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427597 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237598 request.method = "GET";
bncce36dca22015-04-21 22:11:237599 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417600 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107601 request.traffic_annotation =
7602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297603
danakj1fd259a02016-04-16 03:17:097604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167605 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277606
[email protected]a97cca42009-08-14 01:00:297607 // The password contains an escaped character -- for this test to pass it
7608 // will need to be unescaped by HttpNetworkTransaction.
7609 EXPECT_EQ("b%40r", request.url.password());
7610
[email protected]f9ee6b52008-11-08 06:46:237611 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237612 MockWrite(
7613 "GET / HTTP/1.1\r\n"
7614 "Host: www.example.org\r\n"
7615 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237616 };
7617
7618 MockRead data_reads1[] = {
7619 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7620 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7621 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067622 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237623 };
7624
[email protected]2262e3a2012-05-22 16:08:167625 // After the challenge above, the transaction will be restarted using the
7626 // identity from the url (foo, b@r) to answer the challenge.
7627 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237628 MockWrite(
7629 "GET / HTTP/1.1\r\n"
7630 "Host: www.example.org\r\n"
7631 "Connection: keep-alive\r\n"
7632 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167633 };
7634
7635 MockRead data_reads2[] = {
7636 MockRead("HTTP/1.0 200 OK\r\n"),
7637 MockRead("Content-Length: 100\r\n\r\n"),
7638 MockRead(SYNCHRONOUS, OK),
7639 };
7640
[email protected]31a2bfe2010-02-09 08:03:397641 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7642 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167643 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7644 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7646 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237647
[email protected]49639fa2011-12-20 23:22:417648 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207649 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237651 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017652 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167653 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167654
7655 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167656 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167658 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017659 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167660 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227661
bnc691fda62016-08-12 00:43:167662 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527663 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167664
7665 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527666 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167667
7668 EXPECT_EQ(100, response->headers->GetContentLength());
7669
7670 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557671 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167672}
7673
7674// Test the request-challenge-retry sequence for basic auth when there is an
7675// incorrect identity in the URL. The identity from the URL should be used only
7676// once.
bncd16676a2016-07-20 16:23:017677TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167678 HttpRequestInfo request;
7679 request.method = "GET";
7680 // Note: the URL has a username:password in it. The password "baz" is
7681 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237682 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167683
7684 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107685 request.traffic_annotation =
7686 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167687
danakj1fd259a02016-04-16 03:17:097688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167690
7691 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237692 MockWrite(
7693 "GET / HTTP/1.1\r\n"
7694 "Host: www.example.org\r\n"
7695 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167696 };
7697
7698 MockRead data_reads1[] = {
7699 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7700 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7701 MockRead("Content-Length: 10\r\n\r\n"),
7702 MockRead(SYNCHRONOUS, ERR_FAILED),
7703 };
7704
7705 // After the challenge above, the transaction will be restarted using the
7706 // identity from the url (foo, baz) to answer the challenge.
7707 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237708 MockWrite(
7709 "GET / HTTP/1.1\r\n"
7710 "Host: www.example.org\r\n"
7711 "Connection: keep-alive\r\n"
7712 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167713 };
7714
7715 MockRead data_reads2[] = {
7716 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7717 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7718 MockRead("Content-Length: 10\r\n\r\n"),
7719 MockRead(SYNCHRONOUS, ERR_FAILED),
7720 };
7721
7722 // After the challenge above, the transaction will be restarted using the
7723 // identity supplied by the user (foo, bar) to answer the challenge.
7724 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237725 MockWrite(
7726 "GET / HTTP/1.1\r\n"
7727 "Host: www.example.org\r\n"
7728 "Connection: keep-alive\r\n"
7729 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167730 };
7731
7732 MockRead data_reads3[] = {
7733 MockRead("HTTP/1.0 200 OK\r\n"),
7734 MockRead("Content-Length: 100\r\n\r\n"),
7735 MockRead(SYNCHRONOUS, OK),
7736 };
7737
7738 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7739 data_writes1, arraysize(data_writes1));
7740 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7741 data_writes2, arraysize(data_writes2));
7742 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7743 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077744 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7745 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7746 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167747
7748 TestCompletionCallback callback1;
7749
tfarina42834112016-09-22 13:38:207750 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167752
7753 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017754 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167755
bnc691fda62016-08-12 00:43:167756 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167757 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167758 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167760 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017761 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167762 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167763
bnc691fda62016-08-12 00:43:167764 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527765 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167766 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7767
7768 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167769 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167771 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017772 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167773 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167774
bnc691fda62016-08-12 00:43:167775 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527776 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167777
7778 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527779 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167780
7781 EXPECT_EQ(100, response->headers->GetContentLength());
7782
[email protected]ea9dc9a2009-09-05 00:43:327783 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557784 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327785}
7786
[email protected]2217aa22013-10-11 03:03:547787
7788// Test the request-challenge-retry sequence for basic auth when there is a
7789// correct identity in the URL, but its use is being suppressed. The identity
7790// from the URL should never be used.
bncd16676a2016-07-20 16:23:017791TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547792 HttpRequestInfo request;
7793 request.method = "GET";
bncce36dca22015-04-21 22:11:237794 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547795 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:107796 request.traffic_annotation =
7797 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547798
danakj1fd259a02016-04-16 03:17:097799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547801
7802 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237803 MockWrite(
7804 "GET / HTTP/1.1\r\n"
7805 "Host: www.example.org\r\n"
7806 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547807 };
7808
7809 MockRead data_reads1[] = {
7810 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7811 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7812 MockRead("Content-Length: 10\r\n\r\n"),
7813 MockRead(SYNCHRONOUS, ERR_FAILED),
7814 };
7815
7816 // After the challenge above, the transaction will be restarted using the
7817 // identity supplied by the user, not the one in the URL, to answer the
7818 // challenge.
7819 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237820 MockWrite(
7821 "GET / HTTP/1.1\r\n"
7822 "Host: www.example.org\r\n"
7823 "Connection: keep-alive\r\n"
7824 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547825 };
7826
7827 MockRead data_reads3[] = {
7828 MockRead("HTTP/1.0 200 OK\r\n"),
7829 MockRead("Content-Length: 100\r\n\r\n"),
7830 MockRead(SYNCHRONOUS, OK),
7831 };
7832
7833 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7834 data_writes1, arraysize(data_writes1));
7835 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7836 data_writes3, arraysize(data_writes3));
7837 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7838 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7839
7840 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207841 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547843 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017844 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167845 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547846
bnc691fda62016-08-12 00:43:167847 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527848 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547849 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7850
7851 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167852 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547854 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017855 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167856 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547857
bnc691fda62016-08-12 00:43:167858 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527859 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547860
7861 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527862 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547863 EXPECT_EQ(100, response->headers->GetContentLength());
7864
7865 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557866 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547867}
7868
[email protected]f9ee6b52008-11-08 06:46:237869// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017870TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097871 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237872
7873 // Transaction 1: authenticate (foo, bar) on MyRealm1
7874 {
[email protected]1c773ea12009-04-28 19:58:427875 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237876 request.method = "GET";
bncce36dca22015-04-21 22:11:237877 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:107878 request.traffic_annotation =
7879 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237880
bnc691fda62016-08-12 00:43:167881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277882
[email protected]f9ee6b52008-11-08 06:46:237883 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237884 MockWrite(
7885 "GET /x/y/z HTTP/1.1\r\n"
7886 "Host: www.example.org\r\n"
7887 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237888 };
7889
7890 MockRead data_reads1[] = {
7891 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7892 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7893 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067894 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237895 };
7896
7897 // Resend with authorization (username=foo, password=bar)
7898 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237899 MockWrite(
7900 "GET /x/y/z HTTP/1.1\r\n"
7901 "Host: www.example.org\r\n"
7902 "Connection: keep-alive\r\n"
7903 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237904 };
7905
7906 // Sever accepts the authorization.
7907 MockRead data_reads2[] = {
7908 MockRead("HTTP/1.0 200 OK\r\n"),
7909 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067910 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237911 };
7912
[email protected]31a2bfe2010-02-09 08:03:397913 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7914 data_writes1, arraysize(data_writes1));
7915 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7916 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077917 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7918 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237919
[email protected]49639fa2011-12-20 23:22:417920 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237921
tfarina42834112016-09-22 13:38:207922 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237924
7925 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017926 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237927
bnc691fda62016-08-12 00:43:167928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527929 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047930 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237931
[email protected]49639fa2011-12-20 23:22:417932 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237933
bnc691fda62016-08-12 00:43:167934 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7935 callback2.callback());
robpercival214763f2016-07-01 23:27:017936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237937
7938 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017939 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237940
bnc691fda62016-08-12 00:43:167941 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527942 ASSERT_TRUE(response);
7943 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237944 EXPECT_EQ(100, response->headers->GetContentLength());
7945 }
7946
7947 // ------------------------------------------------------------------------
7948
7949 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7950 {
[email protected]1c773ea12009-04-28 19:58:427951 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237952 request.method = "GET";
7953 // Note that Transaction 1 was at /x/y/z, so this is in the same
7954 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237955 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:107956 request.traffic_annotation =
7957 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237958
bnc691fda62016-08-12 00:43:167959 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277960
[email protected]f9ee6b52008-11-08 06:46:237961 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237962 MockWrite(
7963 "GET /x/y/a/b HTTP/1.1\r\n"
7964 "Host: www.example.org\r\n"
7965 "Connection: keep-alive\r\n"
7966 // Send preemptive authorization for MyRealm1
7967 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237968 };
7969
7970 // The server didn't like the preemptive authorization, and
7971 // challenges us for a different realm (MyRealm2).
7972 MockRead data_reads1[] = {
7973 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7974 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7975 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067976 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237977 };
7978
7979 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7980 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237981 MockWrite(
7982 "GET /x/y/a/b HTTP/1.1\r\n"
7983 "Host: www.example.org\r\n"
7984 "Connection: keep-alive\r\n"
7985 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237986 };
7987
7988 // Sever accepts the authorization.
7989 MockRead data_reads2[] = {
7990 MockRead("HTTP/1.0 200 OK\r\n"),
7991 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067992 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237993 };
7994
[email protected]31a2bfe2010-02-09 08:03:397995 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7996 data_writes1, arraysize(data_writes1));
7997 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7998 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077999 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8000 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238001
[email protected]49639fa2011-12-20 23:22:418002 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238003
tfarina42834112016-09-22 13:38:208004 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238006
8007 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018008 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238009
bnc691fda62016-08-12 00:43:168010 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528011 ASSERT_TRUE(response);
8012 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048013 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438014 EXPECT_EQ("http://www.example.org",
8015 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048016 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198017 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238018
[email protected]49639fa2011-12-20 23:22:418019 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238020
bnc691fda62016-08-12 00:43:168021 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8022 callback2.callback());
robpercival214763f2016-07-01 23:27:018023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238024
8025 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018026 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238027
bnc691fda62016-08-12 00:43:168028 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528029 ASSERT_TRUE(response);
8030 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238031 EXPECT_EQ(100, response->headers->GetContentLength());
8032 }
8033
8034 // ------------------------------------------------------------------------
8035
8036 // Transaction 3: Resend a request in MyRealm's protection space --
8037 // succeed with preemptive authorization.
8038 {
[email protected]1c773ea12009-04-28 19:58:428039 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238040 request.method = "GET";
bncce36dca22015-04-21 22:11:238041 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108042 request.traffic_annotation =
8043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238044
bnc691fda62016-08-12 00:43:168045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278046
[email protected]f9ee6b52008-11-08 06:46:238047 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238048 MockWrite(
8049 "GET /x/y/z2 HTTP/1.1\r\n"
8050 "Host: www.example.org\r\n"
8051 "Connection: keep-alive\r\n"
8052 // The authorization for MyRealm1 gets sent preemptively
8053 // (since the url is in the same protection space)
8054 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238055 };
8056
8057 // Sever accepts the preemptive authorization
8058 MockRead data_reads1[] = {
8059 MockRead("HTTP/1.0 200 OK\r\n"),
8060 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068061 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238062 };
8063
[email protected]31a2bfe2010-02-09 08:03:398064 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8065 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078066 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238067
[email protected]49639fa2011-12-20 23:22:418068 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238069
tfarina42834112016-09-22 13:38:208070 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238072
8073 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018074 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238075
bnc691fda62016-08-12 00:43:168076 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528077 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238078
wezca1070932016-05-26 20:30:528079 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238080 EXPECT_EQ(100, response->headers->GetContentLength());
8081 }
8082
8083 // ------------------------------------------------------------------------
8084
8085 // Transaction 4: request another URL in MyRealm (however the
8086 // url is not known to belong to the protection space, so no pre-auth).
8087 {
[email protected]1c773ea12009-04-28 19:58:428088 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238089 request.method = "GET";
bncce36dca22015-04-21 22:11:238090 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108091 request.traffic_annotation =
8092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238093
bnc691fda62016-08-12 00:43:168094 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278095
[email protected]f9ee6b52008-11-08 06:46:238096 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238097 MockWrite(
8098 "GET /x/1 HTTP/1.1\r\n"
8099 "Host: www.example.org\r\n"
8100 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238101 };
8102
8103 MockRead data_reads1[] = {
8104 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8105 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8106 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068107 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238108 };
8109
8110 // Resend with authorization from MyRealm's cache.
8111 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238112 MockWrite(
8113 "GET /x/1 HTTP/1.1\r\n"
8114 "Host: www.example.org\r\n"
8115 "Connection: keep-alive\r\n"
8116 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238117 };
8118
8119 // Sever accepts the authorization.
8120 MockRead data_reads2[] = {
8121 MockRead("HTTP/1.0 200 OK\r\n"),
8122 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068123 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238124 };
8125
[email protected]31a2bfe2010-02-09 08:03:398126 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8127 data_writes1, arraysize(data_writes1));
8128 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8129 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078130 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8131 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238132
[email protected]49639fa2011-12-20 23:22:418133 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238134
tfarina42834112016-09-22 13:38:208135 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238137
8138 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018139 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238140
bnc691fda62016-08-12 00:43:168141 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418142 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168143 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018144 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228145 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018146 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168147 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228148
bnc691fda62016-08-12 00:43:168149 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528150 ASSERT_TRUE(response);
8151 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238152 EXPECT_EQ(100, response->headers->GetContentLength());
8153 }
8154
8155 // ------------------------------------------------------------------------
8156
8157 // Transaction 5: request a URL in MyRealm, but the server rejects the
8158 // cached identity. Should invalidate and re-prompt.
8159 {
[email protected]1c773ea12009-04-28 19:58:428160 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238161 request.method = "GET";
bncce36dca22015-04-21 22:11:238162 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:108163 request.traffic_annotation =
8164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238165
bnc691fda62016-08-12 00:43:168166 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278167
[email protected]f9ee6b52008-11-08 06:46:238168 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238169 MockWrite(
8170 "GET /p/q/t HTTP/1.1\r\n"
8171 "Host: www.example.org\r\n"
8172 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238173 };
8174
8175 MockRead data_reads1[] = {
8176 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8177 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8178 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068179 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238180 };
8181
8182 // Resend with authorization from cache for MyRealm.
8183 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238184 MockWrite(
8185 "GET /p/q/t HTTP/1.1\r\n"
8186 "Host: www.example.org\r\n"
8187 "Connection: keep-alive\r\n"
8188 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238189 };
8190
8191 // Sever rejects the authorization.
8192 MockRead data_reads2[] = {
8193 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8194 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8195 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068196 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238197 };
8198
8199 // At this point we should prompt for new credentials for MyRealm.
8200 // Restart with username=foo3, password=foo4.
8201 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238202 MockWrite(
8203 "GET /p/q/t HTTP/1.1\r\n"
8204 "Host: www.example.org\r\n"
8205 "Connection: keep-alive\r\n"
8206 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238207 };
8208
8209 // Sever accepts the authorization.
8210 MockRead data_reads3[] = {
8211 MockRead("HTTP/1.0 200 OK\r\n"),
8212 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068213 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238214 };
8215
[email protected]31a2bfe2010-02-09 08:03:398216 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8217 data_writes1, arraysize(data_writes1));
8218 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8219 data_writes2, arraysize(data_writes2));
8220 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8221 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078222 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8223 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8224 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238225
[email protected]49639fa2011-12-20 23:22:418226 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238227
tfarina42834112016-09-22 13:38:208228 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238230
8231 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018232 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238233
bnc691fda62016-08-12 00:43:168234 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418235 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168236 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018237 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228238 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018239 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168240 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228241
bnc691fda62016-08-12 00:43:168242 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528243 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048244 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238245
[email protected]49639fa2011-12-20 23:22:418246 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238247
bnc691fda62016-08-12 00:43:168248 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8249 callback3.callback());
robpercival214763f2016-07-01 23:27:018250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238251
[email protected]0757e7702009-03-27 04:00:228252 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018253 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238254
bnc691fda62016-08-12 00:43:168255 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528256 ASSERT_TRUE(response);
8257 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238258 EXPECT_EQ(100, response->headers->GetContentLength());
8259 }
8260}
[email protected]89ceba9a2009-03-21 03:46:068261
[email protected]3c32c5f2010-05-18 15:18:128262// Tests that nonce count increments when multiple auth attempts
8263// are started with the same nonce.
bncd16676a2016-07-20 16:23:018264TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448265 HttpAuthHandlerDigest::Factory* digest_factory =
8266 new HttpAuthHandlerDigest::Factory();
8267 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8268 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8269 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078270 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128272
8273 // Transaction 1: authenticate (foo, bar) on MyRealm1
8274 {
[email protected]3c32c5f2010-05-18 15:18:128275 HttpRequestInfo request;
8276 request.method = "GET";
bncce36dca22015-04-21 22:11:238277 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108278 request.traffic_annotation =
8279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128280
bnc691fda62016-08-12 00:43:168281 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278282
[email protected]3c32c5f2010-05-18 15:18:128283 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238284 MockWrite(
8285 "GET /x/y/z HTTP/1.1\r\n"
8286 "Host: www.example.org\r\n"
8287 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128288 };
8289
8290 MockRead data_reads1[] = {
8291 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8292 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8293 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068294 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128295 };
8296
8297 // Resend with authorization (username=foo, password=bar)
8298 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238299 MockWrite(
8300 "GET /x/y/z HTTP/1.1\r\n"
8301 "Host: www.example.org\r\n"
8302 "Connection: keep-alive\r\n"
8303 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8304 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8305 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8306 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128307 };
8308
8309 // Sever accepts the authorization.
8310 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088311 MockRead("HTTP/1.0 200 OK\r\n"),
8312 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128313 };
8314
8315 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8316 data_writes1, arraysize(data_writes1));
8317 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8318 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078319 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8320 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128321
[email protected]49639fa2011-12-20 23:22:418322 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128323
tfarina42834112016-09-22 13:38:208324 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128326
8327 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018328 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128329
bnc691fda62016-08-12 00:43:168330 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528331 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048332 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128333
[email protected]49639fa2011-12-20 23:22:418334 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128335
bnc691fda62016-08-12 00:43:168336 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8337 callback2.callback());
robpercival214763f2016-07-01 23:27:018338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128339
8340 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018341 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128342
bnc691fda62016-08-12 00:43:168343 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528344 ASSERT_TRUE(response);
8345 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128346 }
8347
8348 // ------------------------------------------------------------------------
8349
8350 // Transaction 2: Request another resource in digestive's protection space.
8351 // This will preemptively add an Authorization header which should have an
8352 // "nc" value of 2 (as compared to 1 in the first use.
8353 {
[email protected]3c32c5f2010-05-18 15:18:128354 HttpRequestInfo request;
8355 request.method = "GET";
8356 // Note that Transaction 1 was at /x/y/z, so this is in the same
8357 // protection space as digest.
bncce36dca22015-04-21 22:11:238358 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108359 request.traffic_annotation =
8360 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128361
bnc691fda62016-08-12 00:43:168362 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278363
[email protected]3c32c5f2010-05-18 15:18:128364 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238365 MockWrite(
8366 "GET /x/y/a/b HTTP/1.1\r\n"
8367 "Host: www.example.org\r\n"
8368 "Connection: keep-alive\r\n"
8369 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8370 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8371 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8372 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128373 };
8374
8375 // Sever accepts the authorization.
8376 MockRead data_reads1[] = {
8377 MockRead("HTTP/1.0 200 OK\r\n"),
8378 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068379 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128380 };
8381
8382 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8383 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078384 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128385
[email protected]49639fa2011-12-20 23:22:418386 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128387
tfarina42834112016-09-22 13:38:208388 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128390
8391 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018392 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128393
bnc691fda62016-08-12 00:43:168394 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528395 ASSERT_TRUE(response);
8396 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128397 }
8398}
8399
[email protected]89ceba9a2009-03-21 03:46:068400// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018401TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068402 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168404 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068405
8406 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168407 trans.read_buf_ = new IOBuffer(15);
8408 trans.read_buf_len_ = 15;
8409 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068410
8411 // Setup state in response_
bnc691fda62016-08-12 00:43:168412 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578413 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088414 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578415 response->response_time = base::Time::Now();
8416 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068417
8418 { // Setup state for response_.vary_data
8419 HttpRequestInfo request;
8420 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8421 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278422 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438423 request.extra_headers.SetHeader("Foo", "1");
8424 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508425 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068426 }
8427
8428 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168429 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068430
8431 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168432 EXPECT_FALSE(trans.read_buf_);
8433 EXPECT_EQ(0, trans.read_buf_len_);
8434 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528435 EXPECT_FALSE(response->auth_challenge);
8436 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048437 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088438 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578439 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068440}
8441
[email protected]bacff652009-03-31 17:50:338442// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018443TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338444 HttpRequestInfo request;
8445 request.method = "GET";
bncce36dca22015-04-21 22:11:238446 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108447 request.traffic_annotation =
8448 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338449
danakj1fd259a02016-04-16 03:17:098450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278452
[email protected]bacff652009-03-31 17:50:338453 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238454 MockWrite(
8455 "GET / HTTP/1.1\r\n"
8456 "Host: www.example.org\r\n"
8457 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338458 };
8459
8460 MockRead data_reads[] = {
8461 MockRead("HTTP/1.0 200 OK\r\n"),
8462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8463 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068464 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338465 };
8466
[email protected]5ecc992a42009-11-11 01:41:598467 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398468 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8469 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068470 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8471 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338472
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8474 session_deps_.socket_factory->AddSocketDataProvider(&data);
8475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338477
[email protected]49639fa2011-12-20 23:22:418478 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338479
tfarina42834112016-09-22 13:38:208480 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338482
8483 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018484 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338485
bnc691fda62016-08-12 00:43:168486 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338488
8489 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018490 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338491
bnc691fda62016-08-12 00:43:168492 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338493
wezca1070932016-05-26 20:30:528494 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338495 EXPECT_EQ(100, response->headers->GetContentLength());
8496}
8497
8498// Test HTTPS connections to a site with a bad certificate, going through a
8499// proxy
bncd16676a2016-07-20 16:23:018500TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498501 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8502 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338503
8504 HttpRequestInfo request;
8505 request.method = "GET";
bncce36dca22015-04-21 22:11:238506 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108507 request.traffic_annotation =
8508 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338509
8510 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178511 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8512 "Host: www.example.org:443\r\n"
8513 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338514 };
8515
8516 MockRead proxy_reads[] = {
8517 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068518 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338519 };
8520
8521 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178522 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8523 "Host: www.example.org:443\r\n"
8524 "Proxy-Connection: keep-alive\r\n\r\n"),
8525 MockWrite("GET / HTTP/1.1\r\n"
8526 "Host: www.example.org\r\n"
8527 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338528 };
8529
8530 MockRead data_reads[] = {
8531 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8532 MockRead("HTTP/1.0 200 OK\r\n"),
8533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8534 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068535 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338536 };
8537
[email protected]31a2bfe2010-02-09 08:03:398538 StaticSocketDataProvider ssl_bad_certificate(
8539 proxy_reads, arraysize(proxy_reads),
8540 proxy_writes, arraysize(proxy_writes));
8541 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8542 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068543 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8544 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338545
[email protected]bb88e1d32013-05-03 23:11:078546 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8547 session_deps_.socket_factory->AddSocketDataProvider(&data);
8548 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8549 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338550
[email protected]49639fa2011-12-20 23:22:418551 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338552
8553 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078554 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338555
danakj1fd259a02016-04-16 03:17:098556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168557 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338558
tfarina42834112016-09-22 13:38:208559 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338561
8562 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018563 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338564
bnc691fda62016-08-12 00:43:168565 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338567
8568 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018569 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338570
bnc691fda62016-08-12 00:43:168571 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338572
wezca1070932016-05-26 20:30:528573 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338574 EXPECT_EQ(100, response->headers->GetContentLength());
8575 }
8576}
8577
[email protected]2df19bb2010-08-25 20:13:468578
8579// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018580TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598581 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498582 ProxyResolutionService::CreateFixedFromPacResult(
8583 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518584 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078585 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468586
8587 HttpRequestInfo request;
8588 request.method = "GET";
bncce36dca22015-04-21 22:11:238589 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108590 request.traffic_annotation =
8591 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468592
8593 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178594 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8595 "Host: www.example.org:443\r\n"
8596 "Proxy-Connection: keep-alive\r\n\r\n"),
8597 MockWrite("GET / HTTP/1.1\r\n"
8598 "Host: www.example.org\r\n"
8599 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468600 };
8601
8602 MockRead data_reads[] = {
8603 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8604 MockRead("HTTP/1.1 200 OK\r\n"),
8605 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8606 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068607 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468608 };
8609
8610 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8611 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068612 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8613 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468614
[email protected]bb88e1d32013-05-03 23:11:078615 session_deps_.socket_factory->AddSocketDataProvider(&data);
8616 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8617 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468618
[email protected]49639fa2011-12-20 23:22:418619 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468620
danakj1fd259a02016-04-16 03:17:098621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168622 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468623
tfarina42834112016-09-22 13:38:208624 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468626
8627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018628 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168629 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468630
wezca1070932016-05-26 20:30:528631 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468632
tbansal2ecbbc72016-10-06 17:15:478633 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468634 EXPECT_TRUE(response->headers->IsKeepAlive());
8635 EXPECT_EQ(200, response->headers->response_code());
8636 EXPECT_EQ(100, response->headers->GetContentLength());
8637 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208638
8639 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168640 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208641 TestLoadTimingNotReusedWithPac(load_timing_info,
8642 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468643}
8644
[email protected]511f6f52010-12-17 03:58:298645// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018646TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598647 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498648 ProxyResolutionService::CreateFixedFromPacResult(
8649 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518650 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078651 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298652
8653 HttpRequestInfo request;
8654 request.method = "GET";
bncce36dca22015-04-21 22:11:238655 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108656 request.traffic_annotation =
8657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298658
8659 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178660 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8661 "Host: www.example.org:443\r\n"
8662 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298663 };
8664
8665 MockRead data_reads[] = {
8666 MockRead("HTTP/1.1 302 Redirect\r\n"),
8667 MockRead("Location: http://login.example.com/\r\n"),
8668 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068669 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298670 };
8671
8672 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8673 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068674 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298675
[email protected]bb88e1d32013-05-03 23:11:078676 session_deps_.socket_factory->AddSocketDataProvider(&data);
8677 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298678
[email protected]49639fa2011-12-20 23:22:418679 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298680
danakj1fd259a02016-04-16 03:17:098681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168682 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298683
tfarina42834112016-09-22 13:38:208684 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298686
8687 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018688 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168689 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298690
wezca1070932016-05-26 20:30:528691 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298692
8693 EXPECT_EQ(302, response->headers->response_code());
8694 std::string url;
8695 EXPECT_TRUE(response->headers->IsRedirect(&url));
8696 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208697
8698 // In the case of redirects from proxies, HttpNetworkTransaction returns
8699 // timing for the proxy connection instead of the connection to the host,
8700 // and no send / receive times.
8701 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8702 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168703 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208704
8705 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198706 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208707
8708 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8709 EXPECT_LE(load_timing_info.proxy_resolve_start,
8710 load_timing_info.proxy_resolve_end);
8711 EXPECT_LE(load_timing_info.proxy_resolve_end,
8712 load_timing_info.connect_timing.connect_start);
8713 ExpectConnectTimingHasTimes(
8714 load_timing_info.connect_timing,
8715 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8716
8717 EXPECT_TRUE(load_timing_info.send_start.is_null());
8718 EXPECT_TRUE(load_timing_info.send_end.is_null());
8719 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298720}
8721
8722// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018723TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498724 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8725 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298726
8727 HttpRequestInfo request;
8728 request.method = "GET";
bncce36dca22015-04-21 22:11:238729 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108730 request.traffic_annotation =
8731 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298732
bncdf80d44fd2016-07-15 20:27:418733 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238734 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418735 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088736 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298737 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418738 CreateMockWrite(conn, 0, SYNCHRONOUS),
8739 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298740 };
8741
8742 static const char* const kExtraHeaders[] = {
8743 "location",
8744 "http://login.example.com/",
8745 };
bnc42331402016-07-25 13:36:158746 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238747 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298748 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418749 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298750 };
8751
rch8e6c6c42015-05-01 14:05:138752 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8753 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068754 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368755 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298756
[email protected]bb88e1d32013-05-03 23:11:078757 session_deps_.socket_factory->AddSocketDataProvider(&data);
8758 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298759
[email protected]49639fa2011-12-20 23:22:418760 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298761
danakj1fd259a02016-04-16 03:17:098762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168763 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298764
tfarina42834112016-09-22 13:38:208765 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018766 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298767
8768 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018769 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168770 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298771
wezca1070932016-05-26 20:30:528772 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298773
8774 EXPECT_EQ(302, response->headers->response_code());
8775 std::string url;
8776 EXPECT_TRUE(response->headers->IsRedirect(&url));
8777 EXPECT_EQ("http://login.example.com/", url);
8778}
8779
[email protected]4eddbc732012-08-09 05:40:178780// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018781TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498782 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8783 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298784
8785 HttpRequestInfo request;
8786 request.method = "GET";
bncce36dca22015-04-21 22:11:238787 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108788 request.traffic_annotation =
8789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298790
8791 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178792 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8793 "Host: www.example.org:443\r\n"
8794 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298795 };
8796
8797 MockRead data_reads[] = {
8798 MockRead("HTTP/1.1 404 Not Found\r\n"),
8799 MockRead("Content-Length: 23\r\n\r\n"),
8800 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068801 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298802 };
8803
8804 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8805 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068806 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298807
[email protected]bb88e1d32013-05-03 23:11:078808 session_deps_.socket_factory->AddSocketDataProvider(&data);
8809 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298810
[email protected]49639fa2011-12-20 23:22:418811 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298812
danakj1fd259a02016-04-16 03:17:098813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298815
tfarina42834112016-09-22 13:38:208816 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298818
8819 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018820 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298821
ttuttle960fcbf2016-04-19 13:26:328822 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298823}
8824
[email protected]4eddbc732012-08-09 05:40:178825// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018826TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498827 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8828 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298829
8830 HttpRequestInfo request;
8831 request.method = "GET";
bncce36dca22015-04-21 22:11:238832 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108833 request.traffic_annotation =
8834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298835
bncdf80d44fd2016-07-15 20:27:418836 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238837 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418838 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088839 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298840 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418841 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298842 };
8843
8844 static const char* const kExtraHeaders[] = {
8845 "location",
8846 "http://login.example.com/",
8847 };
bnc42331402016-07-25 13:36:158848 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238849 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Bence Békyd74f4382018-02-20 18:26:198850 SpdySerializedFrame body(
8851 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298852 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418853 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138854 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298855 };
8856
rch8e6c6c42015-05-01 14:05:138857 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8858 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068859 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368860 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298861
[email protected]bb88e1d32013-05-03 23:11:078862 session_deps_.socket_factory->AddSocketDataProvider(&data);
8863 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298864
[email protected]49639fa2011-12-20 23:22:418865 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298866
danakj1fd259a02016-04-16 03:17:098867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168868 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298869
tfarina42834112016-09-22 13:38:208870 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298872
8873 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018874 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298875
ttuttle960fcbf2016-04-19 13:26:328876 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298877}
8878
[email protected]0c5fb722012-02-28 11:50:358879// Test the request-challenge-retry sequence for basic auth, through
8880// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018881TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358882 HttpRequestInfo request;
8883 request.method = "GET";
bncce36dca22015-04-21 22:11:238884 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358885 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298886 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:108887 request.traffic_annotation =
8888 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358889
8890 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598891 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498892 ProxyResolutionService::CreateFixedFromPacResult(
8893 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518894 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078895 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098896 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358897
8898 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418899 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238900 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418901 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088902 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388903 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358904
bnc691fda62016-08-12 00:43:168905 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358906 // be issuing -- the final header line contains the credentials.
8907 const char* const kAuthCredentials[] = {
8908 "proxy-authorization", "Basic Zm9vOmJhcg==",
8909 };
bncdf80d44fd2016-07-15 20:27:418910 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348911 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238912 HostPortPair("www.example.org", 443)));
8913 // fetch https://www.example.org/ via HTTP
8914 const char get[] =
8915 "GET / HTTP/1.1\r\n"
8916 "Host: www.example.org\r\n"
8917 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418918 SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198919 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358920
8921 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418922 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8923 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358924 };
8925
8926 // The proxy responds to the connect with a 407, using a persistent
8927 // connection.
thestig9d3bb0c2015-01-24 00:49:518928 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358929 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358930 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8931 };
bnc42331402016-07-25 13:36:158932 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418933 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358934
bnc42331402016-07-25 13:36:158935 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358936 const char resp[] = "HTTP/1.1 200 OK\r\n"
8937 "Content-Length: 5\r\n\r\n";
8938
bncdf80d44fd2016-07-15 20:27:418939 SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198940 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
bncdf80d44fd2016-07-15 20:27:418941 SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198942 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358943 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418944 CreateMockRead(conn_auth_resp, 1, ASYNC),
8945 CreateMockRead(conn_resp, 4, ASYNC),
8946 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8947 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138948 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358949 };
8950
rch8e6c6c42015-05-01 14:05:138951 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8952 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078953 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358954 // Negotiate SPDY to the proxy
8955 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368956 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078957 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358958 // Vanilla SSL to the server
8959 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078960 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358961
8962 TestCompletionCallback callback1;
8963
bnc87dcefc2017-05-25 12:47:588964 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198965 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358966
8967 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358969
8970 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018971 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468972 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358973 log.GetEntries(&entries);
8974 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008975 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8976 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358977 ExpectLogContainsSomewhere(
8978 entries, pos,
mikecirone8b85c432016-09-08 19:11:008979 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8980 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358981
8982 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528983 ASSERT_TRUE(response);
8984 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358985 EXPECT_EQ(407, response->headers->response_code());
8986 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528987 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438988 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358989
8990 TestCompletionCallback callback2;
8991
8992 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8993 callback2.callback());
robpercival214763f2016-07-01 23:27:018994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358995
8996 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018997 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358998
8999 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529000 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359001
9002 EXPECT_TRUE(response->headers->IsKeepAlive());
9003 EXPECT_EQ(200, response->headers->response_code());
9004 EXPECT_EQ(5, response->headers->GetContentLength());
9005 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9006
9007 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529008 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359009
[email protected]029c83b62013-01-24 05:28:209010 LoadTimingInfo load_timing_info;
9011 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9012 TestLoadTimingNotReusedWithPac(load_timing_info,
9013 CONNECT_TIMING_HAS_SSL_TIMES);
9014
[email protected]0c5fb722012-02-28 11:50:359015 trans.reset();
9016 session->CloseAllConnections();
9017}
9018
[email protected]7c6f7ba2012-04-03 04:09:299019// Test that an explicitly trusted SPDY proxy can push a resource from an
9020// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019021TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159022 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199023 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159024 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9025 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299026 HttpRequestInfo request;
9027 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109028 request.traffic_annotation =
9029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299030
[email protected]7c6f7ba2012-04-03 04:09:299031 request.method = "GET";
bncce36dca22015-04-21 22:11:239032 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299033 push_request.method = "GET";
9034 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109035 push_request.traffic_annotation =
9036 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299037
tbansal28e68f82016-02-04 02:56:159038 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599039 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499040 ProxyResolutionService::CreateFixedFromPacResult(
9041 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519042 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079043 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509044
inlinechan894515af2016-12-09 02:40:109045 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509046
danakj1fd259a02016-04-16 03:17:099047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299048
bncdf80d44fd2016-07-15 20:27:419049 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459050 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359051 SpdySerializedFrame stream2_priority(
9052 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299053
9054 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419055 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359056 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299057 };
9058
Bence Béky7bf94362018-01-10 13:19:369059 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9060 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9061
bncdf80d44fd2016-07-15 20:27:419062 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159063 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299064
bncdf80d44fd2016-07-15 20:27:419065 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299066
Bence Békyd74f4382018-02-20 18:26:199067 SpdySerializedFrame stream2_body(
9068 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299069
9070 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369071 CreateMockRead(stream2_syn, 1, ASYNC),
9072 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359073 CreateMockRead(stream1_body, 4, ASYNC),
9074 CreateMockRead(stream2_body, 5, ASYNC),
9075 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299076 };
9077
rch8e6c6c42015-05-01 14:05:139078 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9079 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079080 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299081 // Negotiate SPDY to the proxy
9082 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369083 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079084 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299085
bnc87dcefc2017-05-25 12:47:589086 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199087 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299088 TestCompletionCallback callback;
9089 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299091
9092 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019093 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299094 const HttpResponseInfo* response = trans->GetResponseInfo();
9095
bnc87dcefc2017-05-25 12:47:589096 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199097 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509098 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299100
9101 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019102 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299103 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9104
wezca1070932016-05-26 20:30:529105 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299106 EXPECT_TRUE(response->headers->IsKeepAlive());
9107
9108 EXPECT_EQ(200, response->headers->response_code());
9109 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9110
9111 std::string response_data;
9112 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299114 EXPECT_EQ("hello!", response_data);
9115
[email protected]029c83b62013-01-24 05:28:209116 LoadTimingInfo load_timing_info;
9117 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9118 TestLoadTimingNotReusedWithPac(load_timing_info,
9119 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9120
[email protected]7c6f7ba2012-04-03 04:09:299121 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529122 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299123 EXPECT_EQ(200, push_response->headers->response_code());
9124
9125 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019126 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299127 EXPECT_EQ("pushed", response_data);
9128
[email protected]029c83b62013-01-24 05:28:209129 LoadTimingInfo push_load_timing_info;
9130 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9131 TestLoadTimingReusedWithPac(push_load_timing_info);
9132 // The transactions should share a socket ID, despite being for different
9133 // origins.
9134 EXPECT_EQ(load_timing_info.socket_log_id,
9135 push_load_timing_info.socket_log_id);
9136
[email protected]7c6f7ba2012-04-03 04:09:299137 trans.reset();
9138 push_trans.reset();
9139 session->CloseAllConnections();
9140}
9141
[email protected]8c843192012-04-05 07:15:009142// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019143TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159144 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199145 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159146 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9147 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009148 HttpRequestInfo request;
9149
9150 request.method = "GET";
bncce36dca22015-04-21 22:11:239151 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109152 request.traffic_annotation =
9153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009154
Ramin Halavatica8d5252018-03-12 05:33:499155 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9156 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519157 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079158 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509159
9160 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109161 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509162
danakj1fd259a02016-04-16 03:17:099163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009164
bncdf80d44fd2016-07-15 20:27:419165 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459166 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009167
bncdf80d44fd2016-07-15 20:27:419168 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089169 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009170
9171 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419172 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009173 };
9174
bncdf80d44fd2016-07-15 20:27:419175 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159176 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009177
bncdf80d44fd2016-07-15 20:27:419178 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009179
bncdf80d44fd2016-07-15 20:27:419180 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559181 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009182
9183 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419184 CreateMockRead(stream1_reply, 1, ASYNC),
9185 CreateMockRead(stream2_syn, 2, ASYNC),
9186 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599187 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009188 };
9189
rch8e6c6c42015-05-01 14:05:139190 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9191 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079192 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009193 // Negotiate SPDY to the proxy
9194 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369195 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079196 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009197
bnc87dcefc2017-05-25 12:47:589198 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199199 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009200 TestCompletionCallback callback;
9201 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009203
9204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019205 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009206 const HttpResponseInfo* response = trans->GetResponseInfo();
9207
wezca1070932016-05-26 20:30:529208 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009209 EXPECT_TRUE(response->headers->IsKeepAlive());
9210
9211 EXPECT_EQ(200, response->headers->response_code());
9212 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9213
9214 std::string response_data;
9215 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019216 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009217 EXPECT_EQ("hello!", response_data);
9218
9219 trans.reset();
9220 session->CloseAllConnections();
9221}
9222
tbansal8ef1d3e2016-02-03 04:05:429223// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9224// resources.
bncd16676a2016-07-20 16:23:019225TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159226 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199227 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159228 proxy_delegate->set_trusted_spdy_proxy(
9229 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9230
tbansal8ef1d3e2016-02-03 04:05:429231 HttpRequestInfo request;
9232
9233 request.method = "GET";
9234 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109235 request.traffic_annotation =
9236 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429237
9238 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499239 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9240 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429241 BoundTestNetLog log;
9242 session_deps_.net_log = log.bound().net_log();
9243
9244 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109245 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429246
danakj1fd259a02016-04-16 03:17:099247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429248
bncdf80d44fd2016-07-15 20:27:419249 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459250 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359251 SpdySerializedFrame stream2_priority(
9252 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429253
9254 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419255 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359256 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429257 };
9258
bncdf80d44fd2016-07-15 20:27:419259 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159260 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429261
bncdf80d44fd2016-07-15 20:27:419262 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339263 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499264
bncdf80d44fd2016-07-15 20:27:419265 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429266
bncdf80d44fd2016-07-15 20:27:419267 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159268 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429269
bncdf80d44fd2016-07-15 20:27:419270 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429271
9272 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419273 CreateMockRead(stream1_reply, 1, ASYNC),
9274 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359275 CreateMockRead(stream1_body, 4, ASYNC),
9276 CreateMockRead(stream2_body, 5, ASYNC),
9277 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429278 };
9279
9280 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9281 arraysize(spdy_writes));
9282 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9283 // Negotiate SPDY to the proxy
9284 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369285 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429286 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9287
bnc87dcefc2017-05-25 12:47:589288 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199289 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429290 TestCompletionCallback callback;
9291 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429293
9294 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019295 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429296 const HttpResponseInfo* response = trans->GetResponseInfo();
9297
wezca1070932016-05-26 20:30:529298 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429299 EXPECT_TRUE(response->headers->IsKeepAlive());
9300
9301 EXPECT_EQ(200, response->headers->response_code());
9302 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9303
9304 std::string response_data;
9305 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019306 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429307 EXPECT_EQ("hello!", response_data);
9308
9309 trans.reset();
9310 session->CloseAllConnections();
9311}
9312
[email protected]2df19bb2010-08-25 20:13:469313// Test HTTPS connections to a site with a bad certificate, going through an
9314// HTTPS proxy
bncd16676a2016-07-20 16:23:019315TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499316 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9317 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469318
9319 HttpRequestInfo request;
9320 request.method = "GET";
bncce36dca22015-04-21 22:11:239321 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109322 request.traffic_annotation =
9323 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469324
9325 // Attempt to fetch the URL from a server with a bad cert
9326 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179327 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9328 "Host: www.example.org:443\r\n"
9329 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469330 };
9331
9332 MockRead bad_cert_reads[] = {
9333 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069334 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469335 };
9336
9337 // Attempt to fetch the URL with a good cert
9338 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179339 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9340 "Host: www.example.org:443\r\n"
9341 "Proxy-Connection: keep-alive\r\n\r\n"),
9342 MockWrite("GET / HTTP/1.1\r\n"
9343 "Host: www.example.org\r\n"
9344 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469345 };
9346
9347 MockRead good_cert_reads[] = {
9348 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9349 MockRead("HTTP/1.0 200 OK\r\n"),
9350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9351 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069352 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469353 };
9354
9355 StaticSocketDataProvider ssl_bad_certificate(
9356 bad_cert_reads, arraysize(bad_cert_reads),
9357 bad_cert_writes, arraysize(bad_cert_writes));
9358 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9359 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069360 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9361 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469362
9363 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9365 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469367
9368 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9370 session_deps_.socket_factory->AddSocketDataProvider(&data);
9371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469372
[email protected]49639fa2011-12-20 23:22:419373 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469374
danakj1fd259a02016-04-16 03:17:099375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469377
tfarina42834112016-09-22 13:38:209378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469380
9381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019382 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469383
bnc691fda62016-08-12 00:43:169384 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469386
9387 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019388 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469389
bnc691fda62016-08-12 00:43:169390 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469391
wezca1070932016-05-26 20:30:529392 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469393 EXPECT_EQ(100, response->headers->GetContentLength());
9394}
9395
bncd16676a2016-07-20 16:23:019396TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429397 HttpRequestInfo request;
9398 request.method = "GET";
bncce36dca22015-04-21 22:11:239399 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439400 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9401 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109402 request.traffic_annotation =
9403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429404
danakj1fd259a02016-04-16 03:17:099405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279407
[email protected]1c773ea12009-04-28 19:58:429408 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239409 MockWrite(
9410 "GET / HTTP/1.1\r\n"
9411 "Host: www.example.org\r\n"
9412 "Connection: keep-alive\r\n"
9413 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429414 };
9415
9416 // Lastly, the server responds with the actual content.
9417 MockRead data_reads[] = {
9418 MockRead("HTTP/1.0 200 OK\r\n"),
9419 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9420 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069421 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429422 };
9423
[email protected]31a2bfe2010-02-09 08:03:399424 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9425 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079426 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429427
[email protected]49639fa2011-12-20 23:22:419428 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429429
tfarina42834112016-09-22 13:38:209430 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429432
9433 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019434 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429435}
9436
bncd16676a2016-07-20 16:23:019437TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299438 HttpRequestInfo request;
9439 request.method = "GET";
bncce36dca22015-04-21 22:11:239440 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299441 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9442 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109443 request.traffic_annotation =
9444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299445
Ramin Halavatica8d5252018-03-12 05:33:499446 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9447 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279450
[email protected]da81f132010-08-18 23:39:299451 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179452 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9453 "Host: www.example.org:443\r\n"
9454 "Proxy-Connection: keep-alive\r\n"
9455 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299456 };
9457 MockRead data_reads[] = {
9458 // Return an error, so the transaction stops here (this test isn't
9459 // interested in the rest).
9460 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9461 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9462 MockRead("Proxy-Connection: close\r\n\r\n"),
9463 };
9464
9465 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9466 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079467 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299468
[email protected]49639fa2011-12-20 23:22:419469 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299470
tfarina42834112016-09-22 13:38:209471 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299473
9474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019475 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299476}
9477
bncd16676a2016-07-20 16:23:019478TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429479 HttpRequestInfo request;
9480 request.method = "GET";
bncce36dca22015-04-21 22:11:239481 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169482 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9483 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:109484 request.traffic_annotation =
9485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429486
danakj1fd259a02016-04-16 03:17:099487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279489
[email protected]1c773ea12009-04-28 19:58:429490 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239491 MockWrite(
9492 "GET / HTTP/1.1\r\n"
9493 "Host: www.example.org\r\n"
9494 "Connection: keep-alive\r\n"
9495 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429496 };
9497
9498 // Lastly, the server responds with the actual content.
9499 MockRead data_reads[] = {
9500 MockRead("HTTP/1.0 200 OK\r\n"),
9501 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9502 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069503 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429504 };
9505
[email protected]31a2bfe2010-02-09 08:03:399506 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9507 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079508 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429509
[email protected]49639fa2011-12-20 23:22:419510 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429511
tfarina42834112016-09-22 13:38:209512 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429514
9515 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019516 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429517}
9518
bncd16676a2016-07-20 16:23:019519TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429520 HttpRequestInfo request;
9521 request.method = "POST";
bncce36dca22015-04-21 22:11:239522 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109523 request.traffic_annotation =
9524 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429525
danakj1fd259a02016-04-16 03:17:099526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279528
[email protected]1c773ea12009-04-28 19:58:429529 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239530 MockWrite(
9531 "POST / HTTP/1.1\r\n"
9532 "Host: www.example.org\r\n"
9533 "Connection: keep-alive\r\n"
9534 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429535 };
9536
9537 // Lastly, the server responds with the actual content.
9538 MockRead data_reads[] = {
9539 MockRead("HTTP/1.0 200 OK\r\n"),
9540 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9541 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069542 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429543 };
9544
[email protected]31a2bfe2010-02-09 08:03:399545 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9546 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079547 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429548
[email protected]49639fa2011-12-20 23:22:419549 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429550
tfarina42834112016-09-22 13:38:209551 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429553
9554 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019555 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429556}
9557
bncd16676a2016-07-20 16:23:019558TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429559 HttpRequestInfo request;
9560 request.method = "PUT";
bncce36dca22015-04-21 22:11:239561 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109562 request.traffic_annotation =
9563 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429564
danakj1fd259a02016-04-16 03:17:099565 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169566 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279567
[email protected]1c773ea12009-04-28 19:58:429568 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239569 MockWrite(
9570 "PUT / HTTP/1.1\r\n"
9571 "Host: www.example.org\r\n"
9572 "Connection: keep-alive\r\n"
9573 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429574 };
9575
9576 // Lastly, the server responds with the actual content.
9577 MockRead data_reads[] = {
9578 MockRead("HTTP/1.0 200 OK\r\n"),
9579 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9580 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069581 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429582 };
9583
[email protected]31a2bfe2010-02-09 08:03:399584 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9585 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429587
[email protected]49639fa2011-12-20 23:22:419588 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429589
tfarina42834112016-09-22 13:38:209590 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019591 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429592
9593 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019594 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429595}
9596
bncd16676a2016-07-20 16:23:019597TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429598 HttpRequestInfo request;
9599 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239600 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109601 request.traffic_annotation =
9602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429603
danakj1fd259a02016-04-16 03:17:099604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169605 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279606
[email protected]1c773ea12009-04-28 19:58:429607 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139608 MockWrite("HEAD / HTTP/1.1\r\n"
9609 "Host: www.example.org\r\n"
9610 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429611 };
9612
9613 // Lastly, the server responds with the actual content.
9614 MockRead data_reads[] = {
9615 MockRead("HTTP/1.0 200 OK\r\n"),
9616 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9617 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069618 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429619 };
9620
[email protected]31a2bfe2010-02-09 08:03:399621 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9622 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429624
[email protected]49639fa2011-12-20 23:22:419625 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429626
tfarina42834112016-09-22 13:38:209627 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429629
9630 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019631 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429632}
9633
bncd16676a2016-07-20 16:23:019634TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429635 HttpRequestInfo request;
9636 request.method = "GET";
bncce36dca22015-04-21 22:11:239637 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429638 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109639 request.traffic_annotation =
9640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429641
danakj1fd259a02016-04-16 03:17:099642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279644
[email protected]1c773ea12009-04-28 19:58:429645 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239646 MockWrite(
9647 "GET / HTTP/1.1\r\n"
9648 "Host: www.example.org\r\n"
9649 "Connection: keep-alive\r\n"
9650 "Pragma: no-cache\r\n"
9651 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429652 };
9653
9654 // Lastly, the server responds with the actual content.
9655 MockRead data_reads[] = {
9656 MockRead("HTTP/1.0 200 OK\r\n"),
9657 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9658 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069659 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429660 };
9661
[email protected]31a2bfe2010-02-09 08:03:399662 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9663 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079664 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429665
[email protected]49639fa2011-12-20 23:22:419666 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429667
tfarina42834112016-09-22 13:38:209668 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429670
9671 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019672 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429673}
9674
bncd16676a2016-07-20 16:23:019675TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429676 HttpRequestInfo request;
9677 request.method = "GET";
bncce36dca22015-04-21 22:11:239678 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429679 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109680 request.traffic_annotation =
9681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429682
danakj1fd259a02016-04-16 03:17:099683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279685
[email protected]1c773ea12009-04-28 19:58:429686 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239687 MockWrite(
9688 "GET / HTTP/1.1\r\n"
9689 "Host: www.example.org\r\n"
9690 "Connection: keep-alive\r\n"
9691 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429692 };
9693
9694 // Lastly, the server responds with the actual content.
9695 MockRead data_reads[] = {
9696 MockRead("HTTP/1.0 200 OK\r\n"),
9697 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9698 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069699 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429700 };
9701
[email protected]31a2bfe2010-02-09 08:03:399702 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9703 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079704 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429705
[email protected]49639fa2011-12-20 23:22:419706 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429707
tfarina42834112016-09-22 13:38:209708 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429710
9711 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019712 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429713}
9714
bncd16676a2016-07-20 16:23:019715TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429716 HttpRequestInfo request;
9717 request.method = "GET";
bncce36dca22015-04-21 22:11:239718 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439719 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:109720 request.traffic_annotation =
9721 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429722
danakj1fd259a02016-04-16 03:17:099723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279725
[email protected]1c773ea12009-04-28 19:58:429726 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239727 MockWrite(
9728 "GET / HTTP/1.1\r\n"
9729 "Host: www.example.org\r\n"
9730 "Connection: keep-alive\r\n"
9731 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429732 };
9733
9734 // Lastly, the server responds with the actual content.
9735 MockRead data_reads[] = {
9736 MockRead("HTTP/1.0 200 OK\r\n"),
9737 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9738 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069739 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429740 };
9741
[email protected]31a2bfe2010-02-09 08:03:399742 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9743 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079744 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429745
[email protected]49639fa2011-12-20 23:22:419746 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429747
tfarina42834112016-09-22 13:38:209748 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429750
9751 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019752 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429753}
9754
bncd16676a2016-07-20 16:23:019755TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479756 HttpRequestInfo request;
9757 request.method = "GET";
bncce36dca22015-04-21 22:11:239758 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439759 request.extra_headers.SetHeader("referer", "www.foo.com");
9760 request.extra_headers.SetHeader("hEllo", "Kitty");
9761 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:109762 request.traffic_annotation =
9763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479764
danakj1fd259a02016-04-16 03:17:099765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279767
[email protected]270c6412010-03-29 22:02:479768 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239769 MockWrite(
9770 "GET / HTTP/1.1\r\n"
9771 "Host: www.example.org\r\n"
9772 "Connection: keep-alive\r\n"
9773 "referer: www.foo.com\r\n"
9774 "hEllo: Kitty\r\n"
9775 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479776 };
9777
9778 // Lastly, the server responds with the actual content.
9779 MockRead data_reads[] = {
9780 MockRead("HTTP/1.0 200 OK\r\n"),
9781 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9782 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069783 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479784 };
9785
9786 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9787 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079788 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479789
[email protected]49639fa2011-12-20 23:22:419790 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479791
tfarina42834112016-09-22 13:38:209792 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479794
9795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019796 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479797}
9798
bncd16676a2016-07-20 16:23:019799TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279800 HttpRequestInfo request;
9801 request.method = "GET";
bncce36dca22015-04-21 22:11:239802 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109803 request.traffic_annotation =
9804 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279805
Lily Houghton8c2f97d2018-01-22 05:06:599806 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499807 ProxyResolutionService::CreateFixedFromPacResult(
9808 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519809 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079810 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029811
danakj1fd259a02016-04-16 03:17:099812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029814
[email protected]3cd17242009-06-23 02:59:029815 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9816 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9817
9818 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239819 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9820 MockWrite(
9821 "GET / HTTP/1.1\r\n"
9822 "Host: www.example.org\r\n"
9823 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029824
9825 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069826 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029827 MockRead("HTTP/1.0 200 OK\r\n"),
9828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9829 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069830 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029831 };
9832
[email protected]31a2bfe2010-02-09 08:03:399833 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9834 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079835 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029836
[email protected]49639fa2011-12-20 23:22:419837 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029838
tfarina42834112016-09-22 13:38:209839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029841
9842 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019843 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029844
bnc691fda62016-08-12 00:43:169845 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529846 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029847
tbansal2ecbbc72016-10-06 17:15:479848 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209849 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169850 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209851 TestLoadTimingNotReusedWithPac(load_timing_info,
9852 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9853
[email protected]3cd17242009-06-23 02:59:029854 std::string response_text;
bnc691fda62016-08-12 00:43:169855 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019856 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029857 EXPECT_EQ("Payload", response_text);
9858}
9859
bncd16676a2016-07-20 16:23:019860TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279861 HttpRequestInfo request;
9862 request.method = "GET";
bncce36dca22015-04-21 22:11:239863 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109864 request.traffic_annotation =
9865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279866
Lily Houghton8c2f97d2018-01-22 05:06:599867 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499868 ProxyResolutionService::CreateFixedFromPacResult(
9869 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519870 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079871 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029872
danakj1fd259a02016-04-16 03:17:099873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029875
[email protected]3cd17242009-06-23 02:59:029876 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9877 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9878
9879 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239880 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9881 arraysize(write_buffer)),
9882 MockWrite(
9883 "GET / HTTP/1.1\r\n"
9884 "Host: www.example.org\r\n"
9885 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029886
9887 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019888 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9889 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359890 MockRead("HTTP/1.0 200 OK\r\n"),
9891 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9892 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069893 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359894 };
9895
[email protected]31a2bfe2010-02-09 08:03:399896 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9897 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079898 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359899
[email protected]8ddf8322012-02-23 18:08:069900 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359902
[email protected]49639fa2011-12-20 23:22:419903 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359904
tfarina42834112016-09-22 13:38:209905 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359907
9908 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019909 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359910
[email protected]029c83b62013-01-24 05:28:209911 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169912 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209913 TestLoadTimingNotReusedWithPac(load_timing_info,
9914 CONNECT_TIMING_HAS_SSL_TIMES);
9915
bnc691fda62016-08-12 00:43:169916 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529917 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479918 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359919
9920 std::string response_text;
bnc691fda62016-08-12 00:43:169921 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019922 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359923 EXPECT_EQ("Payload", response_text);
9924}
9925
bncd16676a2016-07-20 16:23:019926TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209927 HttpRequestInfo request;
9928 request.method = "GET";
bncce36dca22015-04-21 22:11:239929 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109930 request.traffic_annotation =
9931 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209932
Ramin Halavatica8d5252018-03-12 05:33:499933 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9934 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519935 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079936 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209937
danakj1fd259a02016-04-16 03:17:099938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209940
9941 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9942 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9943
9944 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239945 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9946 MockWrite(
9947 "GET / HTTP/1.1\r\n"
9948 "Host: www.example.org\r\n"
9949 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209950
9951 MockRead data_reads[] = {
9952 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9953 MockRead("HTTP/1.0 200 OK\r\n"),
9954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9955 MockRead("Payload"),
9956 MockRead(SYNCHRONOUS, OK)
9957 };
9958
9959 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9960 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079961 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209962
9963 TestCompletionCallback callback;
9964
tfarina42834112016-09-22 13:38:209965 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209967
9968 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019969 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209970
bnc691fda62016-08-12 00:43:169971 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529972 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209973
9974 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169975 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209976 TestLoadTimingNotReused(load_timing_info,
9977 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9978
9979 std::string response_text;
bnc691fda62016-08-12 00:43:169980 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019981 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209982 EXPECT_EQ("Payload", response_text);
9983}
9984
bncd16676a2016-07-20 16:23:019985TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279986 HttpRequestInfo request;
9987 request.method = "GET";
bncce36dca22015-04-21 22:11:239988 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109989 request.traffic_annotation =
9990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279991
Lily Houghton8c2f97d2018-01-22 05:06:599992 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499993 ProxyResolutionService::CreateFixedFromPacResult(
9994 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519995 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079996 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359997
danakj1fd259a02016-04-16 03:17:099998 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510000
[email protected]e0c27be2009-07-15 13:09:3510001 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10002 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710003 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310004 0x05, // Version
10005 0x01, // Command (CONNECT)
10006 0x00, // Reserved.
10007 0x03, // Address type (DOMAINNAME).
10008 0x0F, // Length of domain (15)
10009 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10010 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710011 };
[email protected]e0c27be2009-07-15 13:09:3510012 const char kSOCKS5OkResponse[] =
10013 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10014
10015 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310016 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10017 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10018 MockWrite(
10019 "GET / HTTP/1.1\r\n"
10020 "Host: www.example.org\r\n"
10021 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510022
10023 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110024 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10025 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510026 MockRead("HTTP/1.0 200 OK\r\n"),
10027 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10028 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610029 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510030 };
10031
[email protected]31a2bfe2010-02-09 08:03:3910032 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10033 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710034 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510035
[email protected]49639fa2011-12-20 23:22:4110036 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510037
tfarina42834112016-09-22 13:38:2010038 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510040
10041 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110042 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510043
bnc691fda62016-08-12 00:43:1610044 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210045 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710046 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510047
[email protected]029c83b62013-01-24 05:28:2010048 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610049 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010050 TestLoadTimingNotReusedWithPac(load_timing_info,
10051 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10052
[email protected]e0c27be2009-07-15 13:09:3510053 std::string response_text;
bnc691fda62016-08-12 00:43:1610054 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110055 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510056 EXPECT_EQ("Payload", response_text);
10057}
10058
bncd16676a2016-07-20 16:23:0110059TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710060 HttpRequestInfo request;
10061 request.method = "GET";
bncce36dca22015-04-21 22:11:2310062 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010063 request.traffic_annotation =
10064 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710065
Lily Houghton8c2f97d2018-01-22 05:06:5910066 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910067 ProxyResolutionService::CreateFixedFromPacResult(
10068 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110069 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710070 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510071
danakj1fd259a02016-04-16 03:17:0910072 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510074
[email protected]e0c27be2009-07-15 13:09:3510075 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10076 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710077 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310078 0x05, // Version
10079 0x01, // Command (CONNECT)
10080 0x00, // Reserved.
10081 0x03, // Address type (DOMAINNAME).
10082 0x0F, // Length of domain (15)
10083 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10084 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710085 };
10086
[email protected]e0c27be2009-07-15 13:09:3510087 const char kSOCKS5OkResponse[] =
10088 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10089
10090 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310091 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10092 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10093 arraysize(kSOCKS5OkRequest)),
10094 MockWrite(
10095 "GET / HTTP/1.1\r\n"
10096 "Host: www.example.org\r\n"
10097 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510098
10099 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110100 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10101 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210102 MockRead("HTTP/1.0 200 OK\r\n"),
10103 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10104 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610105 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210106 };
10107
[email protected]31a2bfe2010-02-09 08:03:3910108 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10109 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710110 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210111
[email protected]8ddf8322012-02-23 18:08:0610112 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210114
[email protected]49639fa2011-12-20 23:22:4110115 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210116
tfarina42834112016-09-22 13:38:2010117 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210119
10120 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110121 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210122
bnc691fda62016-08-12 00:43:1610123 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210124 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710125 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210126
[email protected]029c83b62013-01-24 05:28:2010127 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610128 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010129 TestLoadTimingNotReusedWithPac(load_timing_info,
10130 CONNECT_TIMING_HAS_SSL_TIMES);
10131
[email protected]3cd17242009-06-23 02:59:0210132 std::string response_text;
bnc691fda62016-08-12 00:43:1610133 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110134 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210135 EXPECT_EQ("Payload", response_text);
10136}
10137
[email protected]448d4ca52012-03-04 04:12:2310138namespace {
10139
[email protected]04e5be32009-06-26 20:00:3110140// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610141
10142struct GroupNameTest {
10143 std::string proxy_server;
10144 std::string url;
10145 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810146 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610147};
10148
danakj1fd259a02016-04-16 03:17:0910149std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710150 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910151 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610152
bnc525e175a2016-06-20 12:36:4010153 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310154 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110155 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210156 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110157 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210158 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610159 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610160
10161 return session;
10162}
10163
mmenkee65e7af2015-10-13 17:16:4210164int GroupNameTransactionHelper(const std::string& url,
10165 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610166 HttpRequestInfo request;
10167 request.method = "GET";
10168 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1010169 request.traffic_annotation =
10170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610171
bnc691fda62016-08-12 00:43:1610172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710173
[email protected]49639fa2011-12-20 23:22:4110174 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610175
10176 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010177 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610178}
10179
[email protected]448d4ca52012-03-04 04:12:2310180} // namespace
10181
bncd16676a2016-07-20 16:23:0110182TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610183 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310184 {
10185 "", // unused
10186 "http://www.example.org/direct",
10187 "www.example.org:80",
10188 false,
10189 },
10190 {
10191 "", // unused
10192 "http://[2001:1418:13:1::25]/direct",
10193 "[2001:1418:13:1::25]:80",
10194 false,
10195 },
[email protected]04e5be32009-06-26 20:00:3110196
bncce36dca22015-04-21 22:11:2310197 // SSL Tests
10198 {
10199 "", // unused
10200 "https://www.example.org/direct_ssl",
10201 "ssl/www.example.org:443",
10202 true,
10203 },
10204 {
10205 "", // unused
10206 "https://[2001:1418:13:1::25]/direct",
10207 "ssl/[2001:1418:13:1::25]:443",
10208 true,
10209 },
10210 {
10211 "", // unused
bncaa60ff402016-06-22 19:12:4210212 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310213 "ssl/host.with.alternate:443",
10214 true,
10215 },
[email protected]2d731a32010-04-29 01:04:0610216 };
[email protected]2ff8b312010-04-26 22:20:5410217
viettrungluue4a8b882014-10-16 06:17:3810218 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910219 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910220 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10221 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910222 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010223 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610224
mmenkee65e7af2015-10-13 17:16:4210225 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810226 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810227 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310228 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810229 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910230 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210231 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10232 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810233 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610234
10235 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210236 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910237 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810238 EXPECT_EQ(tests[i].expected_group_name,
10239 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910240 } else {
[email protected]e60e47a2010-07-14 03:37:1810241 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810242 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910243 }
10244 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10245 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10246 // When SSL proxy is not in use, socket must be requested from
10247 // |transport_conn_pool|.
10248 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610249 }
[email protected]2d731a32010-04-29 01:04:0610250}
10251
bncd16676a2016-07-20 16:23:0110252TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610253 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310254 {
Matt Menked1eb6d42018-01-17 04:54:0610255 "http_proxy", "http://www.example.org/http_proxy_normal",
10256 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310257 },
[email protected]2d731a32010-04-29 01:04:0610258
bncce36dca22015-04-21 22:11:2310259 // SSL Tests
10260 {
Matt Menked1eb6d42018-01-17 04:54:0610261 "http_proxy", "https://www.example.org/http_connect_ssl",
10262 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310263 },
[email protected]af3490e2010-10-16 21:02:2910264
bncce36dca22015-04-21 22:11:2310265 {
Matt Menked1eb6d42018-01-17 04:54:0610266 "http_proxy", "https://host.with.alternate/direct",
10267 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310268 },
[email protected]45499252013-01-23 17:12:5610269
bncce36dca22015-04-21 22:11:2310270 {
Matt Menked1eb6d42018-01-17 04:54:0610271 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10272 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310273 },
[email protected]2d731a32010-04-29 01:04:0610274 };
10275
viettrungluue4a8b882014-10-16 06:17:3810276 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910277 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910278 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10279 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910280 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010281 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610282
mmenkee65e7af2015-10-13 17:16:4210283 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610284
[email protected]e60e47a2010-07-14 03:37:1810285 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310286 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410287 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310288 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410289 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910290 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910291 mock_pool_manager->SetSocketPoolForHTTPProxy(
10292 proxy_host, base::WrapUnique(http_proxy_pool));
10293 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10294 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810295 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610296
10297 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210298 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810299 if (tests[i].ssl)
10300 EXPECT_EQ(tests[i].expected_group_name,
10301 ssl_conn_pool->last_group_name_received());
10302 else
10303 EXPECT_EQ(tests[i].expected_group_name,
10304 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610305 }
[email protected]2d731a32010-04-29 01:04:0610306}
10307
bncd16676a2016-07-20 16:23:0110308TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610309 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310310 {
10311 "socks4://socks_proxy:1080",
10312 "http://www.example.org/socks4_direct",
10313 "socks4/www.example.org:80",
10314 false,
10315 },
10316 {
10317 "socks5://socks_proxy:1080",
10318 "http://www.example.org/socks5_direct",
10319 "socks5/www.example.org:80",
10320 false,
10321 },
[email protected]2d731a32010-04-29 01:04:0610322
bncce36dca22015-04-21 22:11:2310323 // SSL Tests
10324 {
10325 "socks4://socks_proxy:1080",
10326 "https://www.example.org/socks4_ssl",
10327 "socks4/ssl/www.example.org:443",
10328 true,
10329 },
10330 {
10331 "socks5://socks_proxy:1080",
10332 "https://www.example.org/socks5_ssl",
10333 "socks5/ssl/www.example.org:443",
10334 true,
10335 },
[email protected]af3490e2010-10-16 21:02:2910336
bncce36dca22015-04-21 22:11:2310337 {
10338 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210339 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310340 "socks4/ssl/host.with.alternate:443",
10341 true,
10342 },
[email protected]04e5be32009-06-26 20:00:3110343 };
10344
viettrungluue4a8b882014-10-16 06:17:3810345 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910346 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910347 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10348 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910349 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010350 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210351
mmenkee65e7af2015-10-13 17:16:4210352 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110353
[email protected]e60e47a2010-07-14 03:37:1810354 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310355 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410356 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310357 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410358 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910359 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910360 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10361 proxy_host, base::WrapUnique(socks_conn_pool));
10362 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10363 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810364 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110365
bnc691fda62016-08-12 00:43:1610366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110367
[email protected]2d731a32010-04-29 01:04:0610368 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210369 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810370 if (tests[i].ssl)
10371 EXPECT_EQ(tests[i].expected_group_name,
10372 ssl_conn_pool->last_group_name_received());
10373 else
10374 EXPECT_EQ(tests[i].expected_group_name,
10375 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110376 }
10377}
10378
bncd16676a2016-07-20 16:23:0110379TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710380 HttpRequestInfo request;
10381 request.method = "GET";
bncce36dca22015-04-21 22:11:2310382 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010383 request.traffic_annotation =
10384 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710385
Ramin Halavatica8d5252018-03-12 05:33:4910386 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10387 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210388
[email protected]69719062010-01-05 20:09:2110389 // This simulates failure resolving all hostnames; that means we will fail
10390 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710391 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210392
danakj1fd259a02016-04-16 03:17:0910393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510395
[email protected]49639fa2011-12-20 23:22:4110396 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510397
tfarina42834112016-09-22 13:38:2010398 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510400
[email protected]9172a982009-06-06 00:30:2510401 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110402 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510403}
10404
Miriam Gershenson2a01b162018-03-22 22:54:4710405// LOAD_BYPASS_CACHE should trigger the host cache bypass.
10406TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2710407 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010408 HttpRequestInfo request_info;
10409 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4710410 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1010411 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010412 request_info.traffic_annotation =
10413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710414
[email protected]a2c2fb92009-07-18 07:31:0410415 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910416 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210417
danakj1fd259a02016-04-16 03:17:0910418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810420
bncce36dca22015-04-21 22:11:2310421 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810422 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910423 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010424 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710425 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310426 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010427 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010428 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710430 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110431 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810432
10433 // Verify that it was added to host cache, by doing a subsequent async lookup
10434 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010435 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710436 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310437 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010438 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010439 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110440 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810441
bncce36dca22015-04-21 22:11:2310442 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810443 // we can tell if the next lookup hit the cache, or the "network".
10444 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310445 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810446
10447 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10448 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610449 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910450 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710451 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810452
[email protected]3b9cca42009-06-16 01:08:2810453 // Run the request.
tfarina42834112016-09-22 13:38:2010454 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110455 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110456 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810457
10458 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310459 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110460 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810461}
10462
[email protected]0877e3d2009-10-17 22:29:5710463// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110464TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710465 HttpRequestInfo request;
10466 request.method = "GET";
10467 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010468 request.traffic_annotation =
10469 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710470
10471 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610472 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710473 };
[email protected]31a2bfe2010-02-09 08:03:3910474 StaticSocketDataProvider data(NULL, 0,
10475 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710476 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710478
[email protected]49639fa2011-12-20 23:22:4110479 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710480
bnc691fda62016-08-12 00:43:1610481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710482
tfarina42834112016-09-22 13:38:2010483 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710485
10486 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110487 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910488
10489 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610490 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910491 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710492}
10493
zmo9528c9f42015-08-04 22:12:0810494// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110495TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710496 HttpRequestInfo request;
10497 request.method = "GET";
10498 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010499 request.traffic_annotation =
10500 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710501
10502 MockRead data_reads[] = {
10503 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610504 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710505 };
10506
[email protected]31a2bfe2010-02-09 08:03:3910507 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710508 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910509 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710510
[email protected]49639fa2011-12-20 23:22:4110511 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710512
bnc691fda62016-08-12 00:43:1610513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710514
tfarina42834112016-09-22 13:38:2010515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710517
10518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110519 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810520
bnc691fda62016-08-12 00:43:1610521 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210522 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810523
wezca1070932016-05-26 20:30:5210524 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810525 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10526
10527 std::string response_data;
bnc691fda62016-08-12 00:43:1610528 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110529 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810530 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910531
10532 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610533 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910534 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710535}
10536
10537// Make sure that a dropped connection while draining the body for auth
10538// restart does the right thing.
bncd16676a2016-07-20 16:23:0110539TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710540 HttpRequestInfo request;
10541 request.method = "GET";
bncce36dca22015-04-21 22:11:2310542 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010543 request.traffic_annotation =
10544 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710545
10546 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310547 MockWrite(
10548 "GET / HTTP/1.1\r\n"
10549 "Host: www.example.org\r\n"
10550 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710551 };
10552
10553 MockRead data_reads1[] = {
10554 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10555 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10556 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10557 MockRead("Content-Length: 14\r\n\r\n"),
10558 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610559 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710560 };
10561
[email protected]31a2bfe2010-02-09 08:03:3910562 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10563 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710564 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710565
bnc691fda62016-08-12 00:43:1610566 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710567 // be issuing -- the final header line contains the credentials.
10568 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310569 MockWrite(
10570 "GET / HTTP/1.1\r\n"
10571 "Host: www.example.org\r\n"
10572 "Connection: keep-alive\r\n"
10573 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710574 };
10575
10576 // Lastly, the server responds with the actual content.
10577 MockRead data_reads2[] = {
10578 MockRead("HTTP/1.1 200 OK\r\n"),
10579 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10580 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610581 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710582 };
10583
[email protected]31a2bfe2010-02-09 08:03:3910584 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10585 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710586 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710588
[email protected]49639fa2011-12-20 23:22:4110589 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710590
bnc691fda62016-08-12 00:43:1610591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010592
tfarina42834112016-09-22 13:38:2010593 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710595
10596 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110597 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710598
bnc691fda62016-08-12 00:43:1610599 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210600 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410601 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710602
[email protected]49639fa2011-12-20 23:22:4110603 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710604
bnc691fda62016-08-12 00:43:1610605 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710607
10608 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110609 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710610
bnc691fda62016-08-12 00:43:1610611 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210612 ASSERT_TRUE(response);
10613 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710614 EXPECT_EQ(100, response->headers->GetContentLength());
10615}
10616
10617// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110618TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910619 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10620 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710621
10622 HttpRequestInfo request;
10623 request.method = "GET";
bncce36dca22015-04-21 22:11:2310624 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010625 request.traffic_annotation =
10626 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710627
10628 MockRead proxy_reads[] = {
10629 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610630 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710631 };
10632
[email protected]31a2bfe2010-02-09 08:03:3910633 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610634 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710635
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->AddSocketDataProvider(&data);
10637 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710638
[email protected]49639fa2011-12-20 23:22:4110639 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710640
[email protected]bb88e1d32013-05-03 23:11:0710641 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710642
danakj1fd259a02016-04-16 03:17:0910643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710645
tfarina42834112016-09-22 13:38:2010646 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710648
10649 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110650 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710651}
10652
bncd16676a2016-07-20 16:23:0110653TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610654 HttpRequestInfo request;
10655 request.method = "GET";
bncce36dca22015-04-21 22:11:2310656 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010657 request.traffic_annotation =
10658 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610659
danakj1fd259a02016-04-16 03:17:0910660 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710662
[email protected]e22e1362009-11-23 21:31:1210663 MockRead data_reads[] = {
10664 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610665 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210666 };
[email protected]9492e4a2010-02-24 00:58:4610667
10668 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710669 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610670
[email protected]49639fa2011-12-20 23:22:4110671 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610672
tfarina42834112016-09-22 13:38:2010673 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610675
robpercival214763f2016-07-01 23:27:0110676 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610677
bnc691fda62016-08-12 00:43:1610678 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210679 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610680
wezca1070932016-05-26 20:30:5210681 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610682 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10683
10684 std::string response_data;
bnc691fda62016-08-12 00:43:1610685 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110686 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210687}
10688
bncd16676a2016-07-20 16:23:0110689TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510690 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210691 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410692 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110693 UploadFileElementReader::ScopedOverridingContentLengthForTests
10694 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310695
danakj1fd259a02016-04-16 03:17:0910696 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910697 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410698 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710699 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210700 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710701
10702 HttpRequestInfo request;
10703 request.method = "POST";
bncce36dca22015-04-21 22:11:2310704 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710705 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010706 request.traffic_annotation =
10707 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710708
danakj1fd259a02016-04-16 03:17:0910709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310711
10712 MockRead data_reads[] = {
10713 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10714 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610715 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310716 };
[email protected]31a2bfe2010-02-09 08:03:3910717 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710718 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310719
[email protected]49639fa2011-12-20 23:22:4110720 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310721
tfarina42834112016-09-22 13:38:2010722 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310724
10725 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110726 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310727
bnc691fda62016-08-12 00:43:1610728 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210729 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310730
maksim.sisove869bf52016-06-23 17:11:5210731 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310732
[email protected]dd3aa792013-07-16 19:10:2310733 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310734}
10735
bncd16676a2016-07-20 16:23:0110736TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510737 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210738 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610739 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810740 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10741 base::WriteFile(temp_file, temp_file_content.c_str(),
10742 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110743 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610744
danakj1fd259a02016-04-16 03:17:0910745 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910746 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410747 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710748 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210749 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710750
10751 HttpRequestInfo request;
10752 request.method = "POST";
bncce36dca22015-04-21 22:11:2310753 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710754 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010755 request.traffic_annotation =
10756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710757
[email protected]999dd8c2013-11-12 06:45:5410758 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610761
[email protected]999dd8c2013-11-12 06:45:5410762 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710763 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610764
[email protected]49639fa2011-12-20 23:22:4110765 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610766
tfarina42834112016-09-22 13:38:2010767 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610769
10770 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110771 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610772
[email protected]dd3aa792013-07-16 19:10:2310773 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610774}
10775
bncd16676a2016-07-20 16:23:0110776TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310777 class FakeUploadElementReader : public UploadElementReader {
10778 public:
Chris Watkins7a41d3552017-12-01 02:13:2710779 FakeUploadElementReader() = default;
10780 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310781
Matt Menkecc1d3a902018-02-05 18:27:3310782 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310783
10784 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310785 int Init(CompletionOnceCallback callback) override {
10786 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310787 return ERR_IO_PENDING;
10788 }
avibf0746c2015-12-09 19:53:1410789 uint64_t GetContentLength() const override { return 0; }
10790 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010791 int Read(IOBuffer* buf,
10792 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310793 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310794 return ERR_FAILED;
10795 }
10796
10797 private:
Matt Menkecc1d3a902018-02-05 18:27:3310798 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310799 };
10800
10801 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910802 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10803 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210804 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310805
10806 HttpRequestInfo request;
10807 request.method = "POST";
bncce36dca22015-04-21 22:11:2310808 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310809 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010810 request.traffic_annotation =
10811 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310812
danakj1fd259a02016-04-16 03:17:0910813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810814 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910815 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310816
10817 StaticSocketDataProvider data;
10818 session_deps_.socket_factory->AddSocketDataProvider(&data);
10819
10820 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010821 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510823 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310824
10825 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310826 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10827 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310828
10829 // Return Init()'s result after the transaction gets destroyed.
10830 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310831 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310832}
10833
[email protected]aeefc9e82010-02-19 16:18:2710834// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110835TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710836 HttpRequestInfo request;
10837 request.method = "GET";
bncce36dca22015-04-21 22:11:2310838 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010839 request.traffic_annotation =
10840 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710841
10842 // First transaction will request a resource and receive a Basic challenge
10843 // with realm="first_realm".
10844 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310845 MockWrite(
10846 "GET / HTTP/1.1\r\n"
10847 "Host: www.example.org\r\n"
10848 "Connection: keep-alive\r\n"
10849 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710850 };
10851 MockRead data_reads1[] = {
10852 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10853 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10854 "\r\n"),
10855 };
10856
bnc691fda62016-08-12 00:43:1610857 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710858 // for first_realm. The server will reject and provide a challenge with
10859 // second_realm.
10860 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310861 MockWrite(
10862 "GET / HTTP/1.1\r\n"
10863 "Host: www.example.org\r\n"
10864 "Connection: keep-alive\r\n"
10865 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10866 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710867 };
10868 MockRead data_reads2[] = {
10869 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10870 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10871 "\r\n"),
10872 };
10873
10874 // This again fails, and goes back to first_realm. Make sure that the
10875 // entry is removed from cache.
10876 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310877 MockWrite(
10878 "GET / HTTP/1.1\r\n"
10879 "Host: www.example.org\r\n"
10880 "Connection: keep-alive\r\n"
10881 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10882 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710883 };
10884 MockRead data_reads3[] = {
10885 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10886 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10887 "\r\n"),
10888 };
10889
10890 // Try one last time (with the correct password) and get the resource.
10891 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310892 MockWrite(
10893 "GET / HTTP/1.1\r\n"
10894 "Host: www.example.org\r\n"
10895 "Connection: keep-alive\r\n"
10896 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10897 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710898 };
10899 MockRead data_reads4[] = {
10900 MockRead("HTTP/1.1 200 OK\r\n"
10901 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010902 "Content-Length: 5\r\n"
10903 "\r\n"
10904 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710905 };
10906
10907 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10908 data_writes1, arraysize(data_writes1));
10909 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10910 data_writes2, arraysize(data_writes2));
10911 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10912 data_writes3, arraysize(data_writes3));
10913 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10914 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710915 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10916 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10917 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10918 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710919
[email protected]49639fa2011-12-20 23:22:4110920 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710921
danakj1fd259a02016-04-16 03:17:0910922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610923 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010924
[email protected]aeefc9e82010-02-19 16:18:2710925 // Issue the first request with Authorize headers. There should be a
10926 // password prompt for first_realm waiting to be filled in after the
10927 // transaction completes.
tfarina42834112016-09-22 13:38:2010928 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710930 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110931 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610932 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210933 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410934 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210935 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410936 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310937 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410938 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910939 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710940
10941 // Issue the second request with an incorrect password. There should be a
10942 // password prompt for second_realm waiting to be filled in after the
10943 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110944 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610945 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10946 callback2.callback());
robpercival214763f2016-07-01 23:27:0110947 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710948 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110949 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610950 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210951 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410952 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210953 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410954 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310955 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410956 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910957 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710958
10959 // Issue the third request with another incorrect password. There should be
10960 // a password prompt for first_realm waiting to be filled in. If the password
10961 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10962 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110963 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610964 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10965 callback3.callback());
robpercival214763f2016-07-01 23:27:0110966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710967 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110968 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610969 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210970 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410971 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210972 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410973 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310974 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410975 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910976 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710977
10978 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110979 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610980 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10981 callback4.callback());
robpercival214763f2016-07-01 23:27:0110982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710983 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110984 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610985 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210986 ASSERT_TRUE(response);
10987 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710988}
10989
Bence Béky230ac612017-08-30 19:17:0810990// Regression test for https://crbug.com/754395.
10991TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10992 MockRead data_reads[] = {
10993 MockRead("HTTP/1.1 200 OK\r\n"),
10994 MockRead(kAlternativeServiceHttpHeader),
10995 MockRead("\r\n"),
10996 MockRead("hello world"),
10997 MockRead(SYNCHRONOUS, OK),
10998 };
10999
11000 HttpRequestInfo request;
11001 request.method = "GET";
11002 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011003 request.traffic_annotation =
11004 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811005
11006 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11007 session_deps_.socket_factory->AddSocketDataProvider(&data);
11008
11009 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911010 ssl.ssl_info.cert =
11011 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11012 ASSERT_TRUE(ssl.ssl_info.cert);
11013 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811014 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11015
11016 TestCompletionCallback callback;
11017
11018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11020
11021 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11023
11024 url::SchemeHostPort test_server(request.url);
11025 HttpServerProperties* http_server_properties =
11026 session->http_server_properties();
11027 EXPECT_TRUE(
11028 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11029
11030 EXPECT_THAT(callback.WaitForResult(), IsOk());
11031
11032 const HttpResponseInfo* response = trans.GetResponseInfo();
11033 ASSERT_TRUE(response);
11034 ASSERT_TRUE(response->headers);
11035 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11036 EXPECT_FALSE(response->was_fetched_via_spdy);
11037 EXPECT_FALSE(response->was_alpn_negotiated);
11038
11039 std::string response_data;
11040 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11041 EXPECT_EQ("hello world", response_data);
11042
11043 EXPECT_TRUE(
11044 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11045}
11046
bncd16676a2016-07-20 16:23:0111047TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211048 MockRead data_reads[] = {
11049 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311050 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211051 MockRead("\r\n"),
11052 MockRead("hello world"),
11053 MockRead(SYNCHRONOUS, OK),
11054 };
11055
11056 HttpRequestInfo request;
11057 request.method = "GET";
bncb26024382016-06-29 02:39:4511058 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011059 request.traffic_annotation =
11060 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211061
11062 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211063 session_deps_.socket_factory->AddSocketDataProvider(&data);
11064
bncb26024382016-06-29 02:39:4511065 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911066 ssl.ssl_info.cert =
11067 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11068 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11070
bncc958faa2015-07-31 18:14:5211071 TestCompletionCallback callback;
11072
danakj1fd259a02016-04-16 03:17:0911073 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211075
tfarina42834112016-09-22 13:38:2011076 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211078
bncb26024382016-06-29 02:39:4511079 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011080 HttpServerProperties* http_server_properties =
11081 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411082 EXPECT_TRUE(
11083 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211084
robpercival214763f2016-07-01 23:27:0111085 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211086
bnc691fda62016-08-12 00:43:1611087 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211088 ASSERT_TRUE(response);
11089 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211090 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11091 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211092 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211093
11094 std::string response_data;
bnc691fda62016-08-12 00:43:1611095 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211096 EXPECT_EQ("hello world", response_data);
11097
zhongyic4de03032017-05-19 04:07:3411098 AlternativeServiceInfoVector alternative_service_info_vector =
11099 http_server_properties->GetAlternativeServiceInfos(test_server);
11100 ASSERT_EQ(1u, alternative_service_info_vector.size());
11101 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11102 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411103 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211104}
11105
bnce3dd56f2016-06-01 10:37:1111106// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111107TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111108 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111109 MockRead data_reads[] = {
11110 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311111 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111112 MockRead("\r\n"),
11113 MockRead("hello world"),
11114 MockRead(SYNCHRONOUS, OK),
11115 };
11116
11117 HttpRequestInfo request;
11118 request.method = "GET";
11119 request.url = GURL("http://www.example.org/");
11120 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011121 request.traffic_annotation =
11122 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111123
11124 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11125 session_deps_.socket_factory->AddSocketDataProvider(&data);
11126
11127 TestCompletionCallback callback;
11128
11129 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611130 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111131
11132 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011133 HttpServerProperties* http_server_properties =
11134 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411135 EXPECT_TRUE(
11136 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111137
tfarina42834112016-09-22 13:38:2011138 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11140 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111141
bnc691fda62016-08-12 00:43:1611142 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111143 ASSERT_TRUE(response);
11144 ASSERT_TRUE(response->headers);
11145 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11146 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211147 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111148
11149 std::string response_data;
bnc691fda62016-08-12 00:43:1611150 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111151 EXPECT_EQ("hello world", response_data);
11152
zhongyic4de03032017-05-19 04:07:3411153 EXPECT_TRUE(
11154 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111155}
11156
bnca86731e2017-04-17 12:31:2811157// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511158// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111159TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511160 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811161 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511162
bnc8bef8da22016-05-30 01:28:2511163 HttpRequestInfo request;
11164 request.method = "GET";
bncb26024382016-06-29 02:39:4511165 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511166 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011167 request.traffic_annotation =
11168 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511169
11170 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11171 StaticSocketDataProvider first_data;
11172 first_data.set_connect_data(mock_connect);
11173 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511174 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611175 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511176 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511177
11178 MockRead data_reads[] = {
11179 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11180 MockRead(ASYNC, OK),
11181 };
11182 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11183 0);
11184 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11185
11186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11187
bnc525e175a2016-06-20 12:36:4011188 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511189 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111190 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11191 444);
bnc8bef8da22016-05-30 01:28:2511192 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111193 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511194 url::SchemeHostPort(request.url), alternative_service, expiration);
11195
bnc691fda62016-08-12 00:43:1611196 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511197 TestCompletionCallback callback;
11198
tfarina42834112016-09-22 13:38:2011199 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511200 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111201 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511202}
11203
bnce3dd56f2016-06-01 10:37:1111204// Regression test for https://crbug.com/615497:
11205// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111206TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111207 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111208 HttpRequestInfo request;
11209 request.method = "GET";
11210 request.url = GURL("http://www.example.org/");
11211 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011212 request.traffic_annotation =
11213 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111214
11215 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11216 StaticSocketDataProvider first_data;
11217 first_data.set_connect_data(mock_connect);
11218 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11219
11220 MockRead data_reads[] = {
11221 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11222 MockRead(ASYNC, OK),
11223 };
11224 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11225 0);
11226 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11227
11228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11229
bnc525e175a2016-06-20 12:36:4011230 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111231 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111232 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111233 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111234 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111235 url::SchemeHostPort(request.url), alternative_service, expiration);
11236
bnc691fda62016-08-12 00:43:1611237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111238 TestCompletionCallback callback;
11239
tfarina42834112016-09-22 13:38:2011240 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111241 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111242 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111243}
11244
bncd16676a2016-07-20 16:23:0111245TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811246 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011248 HttpServerProperties* http_server_properties =
11249 session->http_server_properties();
bncb26024382016-06-29 02:39:4511250 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111251 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811252 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111253 http_server_properties->SetQuicAlternativeService(
11254 test_server, alternative_service, expiration,
11255 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411256 EXPECT_EQ(
11257 1u,
11258 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811259
11260 // Send a clear header.
11261 MockRead data_reads[] = {
11262 MockRead("HTTP/1.1 200 OK\r\n"),
11263 MockRead("Alt-Svc: clear\r\n"),
11264 MockRead("\r\n"),
11265 MockRead("hello world"),
11266 MockRead(SYNCHRONOUS, OK),
11267 };
11268 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
11269 session_deps_.socket_factory->AddSocketDataProvider(&data);
11270
bncb26024382016-06-29 02:39:4511271 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911272 ssl.ssl_info.cert =
11273 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11274 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11276
bnc4f575852015-10-14 18:35:0811277 HttpRequestInfo request;
11278 request.method = "GET";
bncb26024382016-06-29 02:39:4511279 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011280 request.traffic_annotation =
11281 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811282
11283 TestCompletionCallback callback;
11284
bnc691fda62016-08-12 00:43:1611285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811286
tfarina42834112016-09-22 13:38:2011287 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111288 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811289
bnc691fda62016-08-12 00:43:1611290 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211291 ASSERT_TRUE(response);
11292 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811293 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11294 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211295 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811296
11297 std::string response_data;
bnc691fda62016-08-12 00:43:1611298 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811299 EXPECT_EQ("hello world", response_data);
11300
zhongyic4de03032017-05-19 04:07:3411301 EXPECT_TRUE(
11302 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811303}
11304
bncd16676a2016-07-20 16:23:0111305TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211306 MockRead data_reads[] = {
11307 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311308 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11309 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211310 MockRead("hello world"),
11311 MockRead(SYNCHRONOUS, OK),
11312 };
11313
11314 HttpRequestInfo request;
11315 request.method = "GET";
bncb26024382016-06-29 02:39:4511316 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011317 request.traffic_annotation =
11318 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211319
11320 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211321 session_deps_.socket_factory->AddSocketDataProvider(&data);
11322
bncb26024382016-06-29 02:39:4511323 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911324 ssl.ssl_info.cert =
11325 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11326 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11328
bncc958faa2015-07-31 18:14:5211329 TestCompletionCallback callback;
11330
danakj1fd259a02016-04-16 03:17:0911331 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611332 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211333
tfarina42834112016-09-22 13:38:2011334 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111335 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211336
bncb26024382016-06-29 02:39:4511337 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011338 HttpServerProperties* http_server_properties =
11339 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411340 EXPECT_TRUE(
11341 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211342
robpercival214763f2016-07-01 23:27:0111343 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211344
bnc691fda62016-08-12 00:43:1611345 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211346 ASSERT_TRUE(response);
11347 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211348 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11349 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211350 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211351
11352 std::string response_data;
bnc691fda62016-08-12 00:43:1611353 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211354 EXPECT_EQ("hello world", response_data);
11355
zhongyic4de03032017-05-19 04:07:3411356 AlternativeServiceInfoVector alternative_service_info_vector =
11357 http_server_properties->GetAlternativeServiceInfos(test_server);
11358 ASSERT_EQ(2u, alternative_service_info_vector.size());
11359
11360 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11361 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411362 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411363 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11364 1234);
11365 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411366 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211367}
11368
bncd16676a2016-07-20 16:23:0111369TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611370 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211371 HostPortPair alternative("alternative.example.org", 443);
11372 std::string origin_url = "https://origin.example.org:443";
11373 std::string alternative_url = "https://alternative.example.org:443";
11374
11375 // Negotiate HTTP/1.1 with alternative.example.org.
11376 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611377 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11379
11380 // HTTP/1.1 data for request.
11381 MockWrite http_writes[] = {
11382 MockWrite("GET / HTTP/1.1\r\n"
11383 "Host: alternative.example.org\r\n"
11384 "Connection: keep-alive\r\n\r\n"),
11385 };
11386
11387 MockRead http_reads[] = {
11388 MockRead("HTTP/1.1 200 OK\r\n"
11389 "Content-Type: text/html; charset=iso-8859-1\r\n"
11390 "Content-Length: 40\r\n\r\n"
11391 "first HTTP/1.1 response from alternative"),
11392 };
11393 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11394 http_writes, arraysize(http_writes));
11395 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11396
11397 StaticSocketDataProvider data_refused;
11398 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11399 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11400
zhongyi3d4a55e72016-04-22 20:36:4611401 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011403 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211404 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111405 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211406 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111407 http_server_properties->SetQuicAlternativeService(
11408 server, alternative_service, expiration,
11409 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211410 // Mark the QUIC alternative service as broken.
11411 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11412
zhongyi48704c182015-12-07 07:52:0211413 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611414 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211415 request.method = "GET";
11416 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011417 request.traffic_annotation =
11418 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11419
zhongyi48704c182015-12-07 07:52:0211420 TestCompletionCallback callback;
11421 NetErrorDetails details;
11422 EXPECT_FALSE(details.quic_broken);
11423
tfarina42834112016-09-22 13:38:2011424 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611425 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211426 EXPECT_TRUE(details.quic_broken);
11427}
11428
bncd16676a2016-07-20 16:23:0111429TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611430 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211431 HostPortPair alternative1("alternative1.example.org", 443);
11432 HostPortPair alternative2("alternative2.example.org", 443);
11433 std::string origin_url = "https://origin.example.org:443";
11434 std::string alternative_url1 = "https://alternative1.example.org:443";
11435 std::string alternative_url2 = "https://alternative2.example.org:443";
11436
11437 // Negotiate HTTP/1.1 with alternative1.example.org.
11438 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611439 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11441
11442 // HTTP/1.1 data for request.
11443 MockWrite http_writes[] = {
11444 MockWrite("GET / HTTP/1.1\r\n"
11445 "Host: alternative1.example.org\r\n"
11446 "Connection: keep-alive\r\n\r\n"),
11447 };
11448
11449 MockRead http_reads[] = {
11450 MockRead("HTTP/1.1 200 OK\r\n"
11451 "Content-Type: text/html; charset=iso-8859-1\r\n"
11452 "Content-Length: 40\r\n\r\n"
11453 "first HTTP/1.1 response from alternative1"),
11454 };
11455 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11456 http_writes, arraysize(http_writes));
11457 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11458
11459 StaticSocketDataProvider data_refused;
11460 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11461 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11462
danakj1fd259a02016-04-16 03:17:0911463 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011464 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211465 session->http_server_properties();
11466
zhongyi3d4a55e72016-04-22 20:36:4611467 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211468 AlternativeServiceInfoVector alternative_service_info_vector;
11469 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11470
bnc3472afd2016-11-17 15:27:2111471 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111472 alternative_service_info_vector.push_back(
11473 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11474 alternative_service1, expiration,
11475 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111476 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111477 alternative_service_info_vector.push_back(
11478 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11479 alternative_service2, expiration,
11480 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211481
11482 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611483 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211484
11485 // Mark one of the QUIC alternative service as broken.
11486 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411487 EXPECT_EQ(2u,
11488 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211489
zhongyi48704c182015-12-07 07:52:0211490 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211492 request.method = "GET";
11493 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011494 request.traffic_annotation =
11495 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11496
zhongyi48704c182015-12-07 07:52:0211497 TestCompletionCallback callback;
11498 NetErrorDetails details;
11499 EXPECT_FALSE(details.quic_broken);
11500
tfarina42834112016-09-22 13:38:2011501 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611502 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211503 EXPECT_FALSE(details.quic_broken);
11504}
11505
bncd16676a2016-07-20 16:23:0111506TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211507 HttpRequestInfo request;
11508 request.method = "GET";
bncb26024382016-06-29 02:39:4511509 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011510 request.traffic_annotation =
11511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211512
[email protected]d973e99a2012-02-17 21:02:3611513 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211514 StaticSocketDataProvider first_data;
11515 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711516 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511517 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611518 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211520
11521 MockRead data_reads[] = {
11522 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11523 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611524 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211525 };
11526 StaticSocketDataProvider second_data(
11527 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711528 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211529
danakj1fd259a02016-04-16 03:17:0911530 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211531
bnc525e175a2016-06-20 12:36:4011532 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311533 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611534 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111535 // Port must be < 1024, or the header will be ignored (since initial port was
11536 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111537 // Port is ignored by MockConnect anyway.
11538 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11539 666);
bnc7dc7e1b42015-07-28 14:43:1211540 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111541 http_server_properties->SetHttp2AlternativeService(
11542 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211543
bnc691fda62016-08-12 00:43:1611544 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111545 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211546
tfarina42834112016-09-22 13:38:2011547 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111548 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11549 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211550
bnc691fda62016-08-12 00:43:1611551 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211552 ASSERT_TRUE(response);
11553 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211554 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11555
11556 std::string response_data;
bnc691fda62016-08-12 00:43:1611557 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211558 EXPECT_EQ("hello world", response_data);
11559
zhongyic4de03032017-05-19 04:07:3411560 const AlternativeServiceInfoVector alternative_service_info_vector =
11561 http_server_properties->GetAlternativeServiceInfos(server);
11562 ASSERT_EQ(1u, alternative_service_info_vector.size());
11563 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411564 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411565 EXPECT_TRUE(
11566 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211567}
11568
bnc55ff9da2015-08-19 18:42:3511569// Ensure that we are not allowed to redirect traffic via an alternate protocol
11570// to an unrestricted (port >= 1024) when the original traffic was on a
11571// restricted port (port < 1024). Ensure that we can redirect in all other
11572// cases.
bncd16676a2016-07-20 16:23:0111573TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111574 HttpRequestInfo restricted_port_request;
11575 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511576 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111577 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011578 restricted_port_request.traffic_annotation =
11579 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111580
[email protected]d973e99a2012-02-17 21:02:3611581 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111582 StaticSocketDataProvider first_data;
11583 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711584 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111585
11586 MockRead data_reads[] = {
11587 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11588 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611589 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111590 };
11591 StaticSocketDataProvider second_data(
11592 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711593 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511594 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611595 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511596 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111597
danakj1fd259a02016-04-16 03:17:0911598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111599
bnc525e175a2016-06-20 12:36:4011600 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311601 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111602 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111603 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11604 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211605 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111606 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611607 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011608 expiration);
[email protected]3912662a32011-10-04 00:51:1111609
bnc691fda62016-08-12 00:43:1611610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111611 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111612
tfarina42834112016-09-22 13:38:2011613 int rv = trans.Start(&restricted_port_request, callback.callback(),
11614 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111616 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111617 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911618}
[email protected]3912662a32011-10-04 00:51:1111619
bnc55ff9da2015-08-19 18:42:3511620// Ensure that we are allowed to redirect traffic via an alternate protocol to
11621// an unrestricted (port >= 1024) when the original traffic was on a restricted
11622// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111623TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711624 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911625
11626 HttpRequestInfo restricted_port_request;
11627 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511628 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911629 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011630 restricted_port_request.traffic_annotation =
11631 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911632
11633 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11634 StaticSocketDataProvider first_data;
11635 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711636 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911637
11638 MockRead data_reads[] = {
11639 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11640 MockRead("hello world"),
11641 MockRead(ASYNC, OK),
11642 };
11643 StaticSocketDataProvider second_data(
11644 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711645 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511646 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611647 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911649
danakj1fd259a02016-04-16 03:17:0911650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911651
bnc525e175a2016-06-20 12:36:4011652 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911653 session->http_server_properties();
11654 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111655 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11656 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211657 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111658 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611659 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011660 expiration);
[email protected]c54c6962013-02-01 04:53:1911661
bnc691fda62016-08-12 00:43:1611662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911663 TestCompletionCallback callback;
11664
tfarina42834112016-09-22 13:38:2011665 EXPECT_EQ(ERR_IO_PENDING,
11666 trans.Start(&restricted_port_request, callback.callback(),
11667 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911668 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111669 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111670}
11671
bnc55ff9da2015-08-19 18:42:3511672// Ensure that we are not allowed to redirect traffic via an alternate protocol
11673// to an unrestricted (port >= 1024) when the original traffic was on a
11674// restricted port (port < 1024). Ensure that we can redirect in all other
11675// cases.
bncd16676a2016-07-20 16:23:0111676TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111677 HttpRequestInfo restricted_port_request;
11678 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511679 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111680 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011681 restricted_port_request.traffic_annotation =
11682 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111683
[email protected]d973e99a2012-02-17 21:02:3611684 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111685 StaticSocketDataProvider first_data;
11686 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711687 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111688
11689 MockRead data_reads[] = {
11690 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11691 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611692 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111693 };
11694 StaticSocketDataProvider second_data(
11695 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711696 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111697
bncb26024382016-06-29 02:39:4511698 SSLSocketDataProvider ssl(ASYNC, OK);
11699 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11700
danakj1fd259a02016-04-16 03:17:0911701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111702
bnc525e175a2016-06-20 12:36:4011703 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311704 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111705 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111706 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11707 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211708 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111709 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611710 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011711 expiration);
[email protected]3912662a32011-10-04 00:51:1111712
bnc691fda62016-08-12 00:43:1611713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111714 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111715
tfarina42834112016-09-22 13:38:2011716 int rv = trans.Start(&restricted_port_request, callback.callback(),
11717 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111719 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111720 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111721}
11722
bnc55ff9da2015-08-19 18:42:3511723// Ensure that we are not allowed to redirect traffic via an alternate protocol
11724// to an unrestricted (port >= 1024) when the original traffic was on a
11725// restricted port (port < 1024). Ensure that we can redirect in all other
11726// cases.
bncd16676a2016-07-20 16:23:0111727TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111728 HttpRequestInfo unrestricted_port_request;
11729 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511730 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111731 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011732 unrestricted_port_request.traffic_annotation =
11733 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111734
[email protected]d973e99a2012-02-17 21:02:3611735 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111736 StaticSocketDataProvider first_data;
11737 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711738 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111739
11740 MockRead data_reads[] = {
11741 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11742 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611743 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111744 };
11745 StaticSocketDataProvider second_data(
11746 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711747 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511748 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611749 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111751
danakj1fd259a02016-04-16 03:17:0911752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111753
bnc525e175a2016-06-20 12:36:4011754 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311755 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111756 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111757 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11758 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211759 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111760 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611761 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011762 expiration);
[email protected]3912662a32011-10-04 00:51:1111763
bnc691fda62016-08-12 00:43:1611764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111765 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111766
bnc691fda62016-08-12 00:43:1611767 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011768 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111770 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111771 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111772}
11773
bnc55ff9da2015-08-19 18:42:3511774// Ensure that we are not allowed to redirect traffic via an alternate protocol
11775// to an unrestricted (port >= 1024) when the original traffic was on a
11776// restricted port (port < 1024). Ensure that we can redirect in all other
11777// cases.
bncd16676a2016-07-20 16:23:0111778TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111779 HttpRequestInfo unrestricted_port_request;
11780 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511781 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111782 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011783 unrestricted_port_request.traffic_annotation =
11784 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111785
[email protected]d973e99a2012-02-17 21:02:3611786 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111787 StaticSocketDataProvider first_data;
11788 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711789 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111790
11791 MockRead data_reads[] = {
11792 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11793 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611794 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111795 };
11796 StaticSocketDataProvider second_data(
11797 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711798 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111799
bncb26024382016-06-29 02:39:4511800 SSLSocketDataProvider ssl(ASYNC, OK);
11801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11802
danakj1fd259a02016-04-16 03:17:0911803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111804
bnc525e175a2016-06-20 12:36:4011805 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311806 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211807 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111808 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11809 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211810 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111811 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611812 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011813 expiration);
[email protected]3912662a32011-10-04 00:51:1111814
bnc691fda62016-08-12 00:43:1611815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111816 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111817
bnc691fda62016-08-12 00:43:1611818 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011819 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111821 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111822 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111823}
11824
bnc55ff9da2015-08-19 18:42:3511825// Ensure that we are not allowed to redirect traffic via an alternate protocol
11826// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11827// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111828TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211829 HttpRequestInfo request;
11830 request.method = "GET";
bncce36dca22015-04-21 22:11:2311831 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011832 request.traffic_annotation =
11833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211834
11835 // The alternate protocol request will error out before we attempt to connect,
11836 // so only the standard HTTP request will try to connect.
11837 MockRead data_reads[] = {
11838 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11839 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611840 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211841 };
11842 StaticSocketDataProvider data(
11843 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711844 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211845
danakj1fd259a02016-04-16 03:17:0911846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211847
bnc525e175a2016-06-20 12:36:4011848 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211849 session->http_server_properties();
11850 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111851 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11852 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211853 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111854 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611855 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211856
bnc691fda62016-08-12 00:43:1611857 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211858 TestCompletionCallback callback;
11859
tfarina42834112016-09-22 13:38:2011860 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211862 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111863 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211864
bnc691fda62016-08-12 00:43:1611865 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211866 ASSERT_TRUE(response);
11867 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211868 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11869
11870 std::string response_data;
bnc691fda62016-08-12 00:43:1611871 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211872 EXPECT_EQ("hello world", response_data);
11873}
11874
bncd16676a2016-07-20 16:23:0111875TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411876 HttpRequestInfo request;
11877 request.method = "GET";
bncb26024382016-06-29 02:39:4511878 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011879 request.traffic_annotation =
11880 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411881
11882 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211883 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311884 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211885 MockRead("\r\n"),
11886 MockRead("hello world"),
11887 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11888 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411889
11890 StaticSocketDataProvider first_transaction(
11891 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711892 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511893 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611894 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511895 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411896
bnc032658ba2016-09-26 18:17:1511897 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411898
bncdf80d44fd2016-07-15 20:27:4111899 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511900 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111901 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411902
bnc42331402016-07-25 13:36:1511903 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111904 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411905 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111906 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411907 };
11908
rch8e6c6c42015-05-01 14:05:1311909 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11910 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711911 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411912
[email protected]d973e99a2012-02-17 21:02:3611913 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511914 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11915 NULL, 0, NULL, 0);
11916 hanging_non_alternate_protocol_socket.set_connect_data(
11917 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711918 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511919 &hanging_non_alternate_protocol_socket);
11920
[email protected]49639fa2011-12-20 23:22:4111921 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411922
danakj1fd259a02016-04-16 03:17:0911923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811924 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911925 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411926
tfarina42834112016-09-22 13:38:2011927 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111928 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11929 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411930
11931 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211932 ASSERT_TRUE(response);
11933 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411934 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11935
11936 std::string response_data;
robpercival214763f2016-07-01 23:27:0111937 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411938 EXPECT_EQ("hello world", response_data);
11939
bnc87dcefc2017-05-25 12:47:5811940 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911941 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411942
tfarina42834112016-09-22 13:38:2011943 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11945 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411946
11947 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211948 ASSERT_TRUE(response);
11949 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211950 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311951 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211952 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411953
robpercival214763f2016-07-01 23:27:0111954 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411955 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411956}
11957
bncd16676a2016-07-20 16:23:0111958TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511959 HttpRequestInfo request;
11960 request.method = "GET";
bncb26024382016-06-29 02:39:4511961 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011962 request.traffic_annotation =
11963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511964
bncb26024382016-06-29 02:39:4511965 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511966 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211967 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311968 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211969 MockRead("\r\n"),
11970 MockRead("hello world"),
11971 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11972 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511973 };
11974
bncb26024382016-06-29 02:39:4511975 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11976 0);
11977 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511978
bncb26024382016-06-29 02:39:4511979 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911980 ssl_http11.ssl_info.cert =
11981 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11982 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11984
11985 // Second transaction starts an alternative and a non-alternative Job.
11986 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611987 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811988 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11989 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811990 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11991
11992 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11993 hanging_socket2.set_connect_data(never_finishing_connect);
11994 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511995
bncb26024382016-06-29 02:39:4511996 // Third transaction starts an alternative and a non-alternative job.
11997 // The non-alternative job hangs, but the alternative one succeeds.
11998 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111999 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512000 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112001 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512002 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512003 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112004 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512005 };
bnc42331402016-07-25 13:36:1512006 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112007 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512008 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112009 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512010 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112011 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12012 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312013 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512014 };
12015
rch8e6c6c42015-05-01 14:05:1312016 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12017 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712018 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512019
bnc032658ba2016-09-26 18:17:1512020 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512021
mmenkecc2298e2015-12-07 18:20:1812022 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
12023 hanging_socket3.set_connect_data(never_finishing_connect);
12024 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512025
danakj1fd259a02016-04-16 03:17:0912026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112027 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012028 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512029
tfarina42834112016-09-22 13:38:2012030 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12032 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512033
12034 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212035 ASSERT_TRUE(response);
12036 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512037 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12038
12039 std::string response_data;
robpercival214763f2016-07-01 23:27:0112040 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512041 EXPECT_EQ("hello world", response_data);
12042
[email protected]49639fa2011-12-20 23:22:4112043 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012044 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012045 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512047
[email protected]49639fa2011-12-20 23:22:4112048 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012049 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012050 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112051 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512052
robpercival214763f2016-07-01 23:27:0112053 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12054 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512055
12056 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212057 ASSERT_TRUE(response);
12058 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212059 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512060 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212061 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112062 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512063 EXPECT_EQ("hello!", response_data);
12064
12065 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212066 ASSERT_TRUE(response);
12067 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212068 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512069 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212070 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112071 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512072 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512073}
12074
bncd16676a2016-07-20 16:23:0112075TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512076 HttpRequestInfo request;
12077 request.method = "GET";
bncb26024382016-06-29 02:39:4512078 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012079 request.traffic_annotation =
12080 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512081
12082 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212083 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312084 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212085 MockRead("\r\n"),
12086 MockRead("hello world"),
12087 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12088 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512089 };
12090
12091 StaticSocketDataProvider first_transaction(
12092 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712093 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512094
[email protected]8ddf8322012-02-23 18:08:0612095 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912096 ssl.ssl_info.cert =
12097 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12098 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512100
[email protected]d973e99a2012-02-17 21:02:3612101 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512102 StaticSocketDataProvider hanging_alternate_protocol_socket(
12103 NULL, 0, NULL, 0);
12104 hanging_alternate_protocol_socket.set_connect_data(
12105 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712106 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512107 &hanging_alternate_protocol_socket);
12108
bncb26024382016-06-29 02:39:4512109 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1812110 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
12111 NULL, 0);
12112 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512114
[email protected]49639fa2011-12-20 23:22:4112115 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512116
danakj1fd259a02016-04-16 03:17:0912117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812118 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912119 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512120
tfarina42834112016-09-22 13:38:2012121 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12123 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512124
12125 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212126 ASSERT_TRUE(response);
12127 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512128 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12129
12130 std::string response_data;
robpercival214763f2016-07-01 23:27:0112131 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512132 EXPECT_EQ("hello world", response_data);
12133
bnc87dcefc2017-05-25 12:47:5812134 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912135 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512136
tfarina42834112016-09-22 13:38:2012137 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12139 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512140
12141 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212142 ASSERT_TRUE(response);
12143 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512144 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12145 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212146 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512147
robpercival214763f2016-07-01 23:27:0112148 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512149 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512150}
12151
[email protected]631f1322010-04-30 17:59:1112152class CapturingProxyResolver : public ProxyResolver {
12153 public:
Chris Watkins7a41d3552017-12-01 02:13:2712154 CapturingProxyResolver() = default;
12155 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112156
dchengb03027d2014-10-21 12:00:2012157 int GetProxyForURL(const GURL& url,
12158 ProxyInfo* results,
12159 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512160 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012161 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012162 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12163 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212164 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112165 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212166 return OK;
[email protected]631f1322010-04-30 17:59:1112167 }
12168
[email protected]24476402010-07-20 20:55:1712169 const std::vector<GURL>& resolved() const { return resolved_; }
12170
12171 private:
[email protected]631f1322010-04-30 17:59:1112172 std::vector<GURL> resolved_;
12173
12174 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12175};
12176
sammce64b2362015-04-29 03:50:2312177class CapturingProxyResolverFactory : public ProxyResolverFactory {
12178 public:
12179 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12180 : ProxyResolverFactory(false), resolver_(resolver) {}
12181
Lily Houghton99597862018-03-07 16:40:4212182 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12183 std::unique_ptr<ProxyResolver>* resolver,
12184 const net::CompletionCallback& callback,
12185 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912186 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312187 return OK;
12188 }
12189
12190 private:
12191 ProxyResolver* resolver_;
12192};
12193
bnc2e884782016-08-11 19:45:1912194// Test that proxy is resolved using the origin url,
12195// regardless of the alternative server.
12196TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12197 // Configure proxy to bypass www.example.org, which is the origin URL.
12198 ProxyConfig proxy_config;
12199 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12200 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912201 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12202 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912203
12204 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912205 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912206 &capturing_proxy_resolver);
12207
12208 TestNetLog net_log;
12209
Lily Houghton8c2f97d2018-01-22 05:06:5912210 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1912211 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12212 &net_log);
12213
12214 session_deps_.net_log = &net_log;
12215
12216 // Configure alternative service with a hostname that is not bypassed by the
12217 // proxy.
12218 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12219 HttpServerProperties* http_server_properties =
12220 session->http_server_properties();
12221 url::SchemeHostPort server("https", "www.example.org", 443);
12222 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112223 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912224 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112225 http_server_properties->SetHttp2AlternativeService(
12226 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912227
12228 // Non-alternative job should hang.
12229 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
12230 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
12231 nullptr, 0);
12232 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12233 session_deps_.socket_factory->AddSocketDataProvider(
12234 &hanging_alternate_protocol_socket);
12235
bnc032658ba2016-09-26 18:17:1512236 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912237
12238 HttpRequestInfo request;
12239 request.method = "GET";
12240 request.url = GURL("https://www.example.org/");
12241 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012242 request.traffic_annotation =
12243 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912244
12245 SpdySerializedFrame req(
12246 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12247
12248 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12249
12250 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12251 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12252 MockRead spdy_reads[] = {
12253 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12254 };
12255
12256 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12257 arraysize(spdy_writes));
12258 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12259
12260 TestCompletionCallback callback;
12261
12262 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12263
tfarina42834112016-09-22 13:38:2012264 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912265 EXPECT_THAT(callback.GetResult(rv), IsOk());
12266
12267 const HttpResponseInfo* response = trans.GetResponseInfo();
12268 ASSERT_TRUE(response);
12269 ASSERT_TRUE(response->headers);
12270 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12271 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212272 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912273
12274 std::string response_data;
12275 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12276 EXPECT_EQ("hello!", response_data);
12277
12278 // Origin host bypasses proxy, no resolution should have happened.
12279 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12280}
12281
bncd16676a2016-07-20 16:23:0112282TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112283 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212284 proxy_config.set_auto_detect(true);
12285 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112286
sammc5dd160c2015-04-02 02:43:1312287 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912288 session_deps_.proxy_resolution_service =
12289 std::make_unique<ProxyResolutionService>(
12290 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12291 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12292 std::make_unique<CapturingProxyResolverFactory>(
12293 &capturing_proxy_resolver),
12294 nullptr);
vishal.b62985ca92015-04-17 08:45:5112295 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712296 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112297
12298 HttpRequestInfo request;
12299 request.method = "GET";
bncb26024382016-06-29 02:39:4512300 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012301 request.traffic_annotation =
12302 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112303
12304 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212305 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312306 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212307 MockRead("\r\n"),
12308 MockRead("hello world"),
12309 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12310 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112311 };
12312
12313 StaticSocketDataProvider first_transaction(
12314 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712315 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512316 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612317 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112319
bnc032658ba2016-09-26 18:17:1512320 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112321
bncdf80d44fd2016-07-15 20:27:4112322 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512323 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112324 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312325 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512326 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12327 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312328 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112329 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112330 };
12331
[email protected]d911f1b2010-05-05 22:39:4212332 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12333
bnc42331402016-07-25 13:36:1512334 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112335 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112336 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112337 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12338 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112339 };
12340
rch8e6c6c42015-05-01 14:05:1312341 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12342 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712343 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112344
[email protected]d973e99a2012-02-17 21:02:3612345 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512346 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12347 NULL, 0, NULL, 0);
12348 hanging_non_alternate_protocol_socket.set_connect_data(
12349 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712350 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512351 &hanging_non_alternate_protocol_socket);
12352
[email protected]49639fa2011-12-20 23:22:4112353 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112354
danakj1fd259a02016-04-16 03:17:0912355 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812356 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912357 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112358
tfarina42834112016-09-22 13:38:2012359 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12361 EXPECT_THAT(callback.WaitForResult(), IsOk());
12362
12363 const HttpResponseInfo* response = trans->GetResponseInfo();
12364 ASSERT_TRUE(response);
12365 ASSERT_TRUE(response->headers);
12366 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12367 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212368 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112369
12370 std::string response_data;
12371 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12372 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112373
bnc87dcefc2017-05-25 12:47:5812374 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912375 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112376
tfarina42834112016-09-22 13:38:2012377 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12379 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112380
mmenkea2dcd3bf2016-08-16 21:49:4112381 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212382 ASSERT_TRUE(response);
12383 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212384 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312385 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212386 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112387
robpercival214763f2016-07-01 23:27:0112388 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112389 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512390 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12391 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312392 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312393 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312394 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112395
[email protected]029c83b62013-01-24 05:28:2012396 LoadTimingInfo load_timing_info;
12397 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12398 TestLoadTimingNotReusedWithPac(load_timing_info,
12399 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112400}
[email protected]631f1322010-04-30 17:59:1112401
bncd16676a2016-07-20 16:23:0112402TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812403 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412404 HttpRequestInfo request;
12405 request.method = "GET";
bncb26024382016-06-29 02:39:4512406 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012407 request.traffic_annotation =
12408 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412409
12410 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212411 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312412 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212413 MockRead("\r\n"),
12414 MockRead("hello world"),
12415 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412416 };
12417
12418 StaticSocketDataProvider first_transaction(
12419 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712420 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512421 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612422 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412424
bnc032658ba2016-09-26 18:17:1512425 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412426
bncdf80d44fd2016-07-15 20:27:4112427 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512428 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112429 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412430
bnc42331402016-07-25 13:36:1512431 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112432 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412433 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112434 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412435 };
12436
rch8e6c6c42015-05-01 14:05:1312437 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12438 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712439 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412440
[email protected]83039bb2011-12-09 18:43:5512441 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412442
danakj1fd259a02016-04-16 03:17:0912443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412444
bnc87dcefc2017-05-25 12:47:5812445 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912446 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412447
tfarina42834112016-09-22 13:38:2012448 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12450 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412451
12452 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212453 ASSERT_TRUE(response);
12454 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412455 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12456
12457 std::string response_data;
robpercival214763f2016-07-01 23:27:0112458 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412459 EXPECT_EQ("hello world", response_data);
12460
12461 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512462 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012463 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412464 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712465 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212466 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812467
bnc87dcefc2017-05-25 12:47:5812468 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912469 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412470
tfarina42834112016-09-22 13:38:2012471 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12473 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412474
12475 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212476 ASSERT_TRUE(response);
12477 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212478 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312479 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212480 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412481
robpercival214763f2016-07-01 23:27:0112482 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412483 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212484}
12485
[email protected]044de0642010-06-17 10:42:1512486// GenerateAuthToken is a mighty big test.
12487// It tests all permutation of GenerateAuthToken behavior:
12488// - Synchronous and Asynchronous completion.
12489// - OK or error on completion.
12490// - Direct connection, non-authenticating proxy, and authenticating proxy.
12491// - HTTP or HTTPS backend (to include proxy tunneling).
12492// - Non-authenticating and authenticating backend.
12493//
[email protected]fe3b7dc2012-02-03 19:52:0912494// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512495// problems generating an auth token for an authenticating proxy, we don't
12496// need to test all permutations of the backend server).
12497//
12498// The test proceeds by going over each of the configuration cases, and
12499// potentially running up to three rounds in each of the tests. The TestConfig
12500// specifies both the configuration for the test as well as the expectations
12501// for the results.
bncd16676a2016-07-20 16:23:0112502TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012503 static const char kServer[] = "http://www.example.com";
12504 static const char kSecureServer[] = "https://www.example.com";
12505 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512506
12507 enum AuthTiming {
12508 AUTH_NONE,
12509 AUTH_SYNC,
12510 AUTH_ASYNC,
12511 };
12512
12513 const MockWrite kGet(
12514 "GET / HTTP/1.1\r\n"
12515 "Host: www.example.com\r\n"
12516 "Connection: keep-alive\r\n\r\n");
12517 const MockWrite kGetProxy(
12518 "GET http://www.example.com/ HTTP/1.1\r\n"
12519 "Host: www.example.com\r\n"
12520 "Proxy-Connection: keep-alive\r\n\r\n");
12521 const MockWrite kGetAuth(
12522 "GET / HTTP/1.1\r\n"
12523 "Host: www.example.com\r\n"
12524 "Connection: keep-alive\r\n"
12525 "Authorization: auth_token\r\n\r\n");
12526 const MockWrite kGetProxyAuth(
12527 "GET http://www.example.com/ HTTP/1.1\r\n"
12528 "Host: www.example.com\r\n"
12529 "Proxy-Connection: keep-alive\r\n"
12530 "Proxy-Authorization: auth_token\r\n\r\n");
12531 const MockWrite kGetAuthThroughProxy(
12532 "GET http://www.example.com/ HTTP/1.1\r\n"
12533 "Host: www.example.com\r\n"
12534 "Proxy-Connection: keep-alive\r\n"
12535 "Authorization: auth_token\r\n\r\n");
12536 const MockWrite kGetAuthWithProxyAuth(
12537 "GET http://www.example.com/ HTTP/1.1\r\n"
12538 "Host: www.example.com\r\n"
12539 "Proxy-Connection: keep-alive\r\n"
12540 "Proxy-Authorization: auth_token\r\n"
12541 "Authorization: auth_token\r\n\r\n");
12542 const MockWrite kConnect(
12543 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712544 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512545 "Proxy-Connection: keep-alive\r\n\r\n");
12546 const MockWrite kConnectProxyAuth(
12547 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712548 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512549 "Proxy-Connection: keep-alive\r\n"
12550 "Proxy-Authorization: auth_token\r\n\r\n");
12551
12552 const MockRead kSuccess(
12553 "HTTP/1.1 200 OK\r\n"
12554 "Content-Type: text/html; charset=iso-8859-1\r\n"
12555 "Content-Length: 3\r\n\r\n"
12556 "Yes");
12557 const MockRead kFailure(
12558 "Should not be called.");
12559 const MockRead kServerChallenge(
12560 "HTTP/1.1 401 Unauthorized\r\n"
12561 "WWW-Authenticate: Mock realm=server\r\n"
12562 "Content-Type: text/html; charset=iso-8859-1\r\n"
12563 "Content-Length: 14\r\n\r\n"
12564 "Unauthorized\r\n");
12565 const MockRead kProxyChallenge(
12566 "HTTP/1.1 407 Unauthorized\r\n"
12567 "Proxy-Authenticate: Mock realm=proxy\r\n"
12568 "Proxy-Connection: close\r\n"
12569 "Content-Type: text/html; charset=iso-8859-1\r\n"
12570 "Content-Length: 14\r\n\r\n"
12571 "Unauthorized\r\n");
12572 const MockRead kProxyConnected(
12573 "HTTP/1.1 200 Connection Established\r\n\r\n");
12574
12575 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12576 // no constructors, but the C++ compiler on Windows warns about
12577 // unspecified data in compound literals. So, moved to using constructors,
12578 // and TestRound's created with the default constructor should not be used.
12579 struct TestRound {
12580 TestRound()
12581 : expected_rv(ERR_UNEXPECTED),
12582 extra_write(NULL),
12583 extra_read(NULL) {
12584 }
12585 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12586 int expected_rv_arg)
12587 : write(write_arg),
12588 read(read_arg),
12589 expected_rv(expected_rv_arg),
12590 extra_write(NULL),
12591 extra_read(NULL) {
12592 }
12593 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12594 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112595 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512596 : write(write_arg),
12597 read(read_arg),
12598 expected_rv(expected_rv_arg),
12599 extra_write(extra_write_arg),
12600 extra_read(extra_read_arg) {
12601 }
12602 MockWrite write;
12603 MockRead read;
12604 int expected_rv;
12605 const MockWrite* extra_write;
12606 const MockRead* extra_read;
12607 };
12608
12609 static const int kNoSSL = 500;
12610
12611 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112612 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112613 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512614 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112615 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112616 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512617 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112618 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512619 int num_auth_rounds;
12620 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612621 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512622 } test_configs[] = {
asankac93076192016-10-03 15:46:0212623 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112624 {__LINE__,
12625 nullptr,
asankac93076192016-10-03 15:46:0212626 AUTH_NONE,
12627 OK,
12628 kServer,
12629 AUTH_NONE,
12630 OK,
12631 1,
12632 kNoSSL,
12633 {TestRound(kGet, kSuccess, OK)}},
12634 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112635 {__LINE__,
12636 nullptr,
asankac93076192016-10-03 15:46:0212637 AUTH_NONE,
12638 OK,
12639 kServer,
12640 AUTH_SYNC,
12641 OK,
12642 2,
12643 kNoSSL,
12644 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512645 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112646 {__LINE__,
12647 nullptr,
asankac93076192016-10-03 15:46:0212648 AUTH_NONE,
12649 OK,
12650 kServer,
12651 AUTH_SYNC,
12652 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612653 3,
12654 kNoSSL,
12655 {TestRound(kGet, kServerChallenge, OK),
12656 TestRound(kGet, kServerChallenge, OK),
12657 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112658 {__LINE__,
12659 nullptr,
asankae2257db2016-10-11 22:03:1612660 AUTH_NONE,
12661 OK,
12662 kServer,
12663 AUTH_SYNC,
12664 ERR_UNSUPPORTED_AUTH_SCHEME,
12665 2,
12666 kNoSSL,
12667 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112668 {__LINE__,
12669 nullptr,
asankae2257db2016-10-11 22:03:1612670 AUTH_NONE,
12671 OK,
12672 kServer,
12673 AUTH_SYNC,
12674 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12675 2,
12676 kNoSSL,
12677 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112678 {__LINE__,
12679 kProxy,
asankae2257db2016-10-11 22:03:1612680 AUTH_SYNC,
12681 ERR_FAILED,
12682 kServer,
12683 AUTH_NONE,
12684 OK,
12685 2,
12686 kNoSSL,
12687 {TestRound(kGetProxy, kProxyChallenge, OK),
12688 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112689 {__LINE__,
12690 kProxy,
asankae2257db2016-10-11 22:03:1612691 AUTH_ASYNC,
12692 ERR_FAILED,
12693 kServer,
12694 AUTH_NONE,
12695 OK,
12696 2,
12697 kNoSSL,
12698 {TestRound(kGetProxy, kProxyChallenge, OK),
12699 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112700 {__LINE__,
12701 nullptr,
asankae2257db2016-10-11 22:03:1612702 AUTH_NONE,
12703 OK,
12704 kServer,
12705 AUTH_SYNC,
12706 ERR_FAILED,
asankac93076192016-10-03 15:46:0212707 2,
12708 kNoSSL,
12709 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612710 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112711 {__LINE__,
12712 nullptr,
asankae2257db2016-10-11 22:03:1612713 AUTH_NONE,
12714 OK,
12715 kServer,
12716 AUTH_ASYNC,
12717 ERR_FAILED,
12718 2,
12719 kNoSSL,
12720 {TestRound(kGet, kServerChallenge, OK),
12721 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112722 {__LINE__,
12723 nullptr,
asankac93076192016-10-03 15:46:0212724 AUTH_NONE,
12725 OK,
12726 kServer,
12727 AUTH_ASYNC,
12728 OK,
12729 2,
12730 kNoSSL,
12731 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512732 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112733 {__LINE__,
12734 nullptr,
asankac93076192016-10-03 15:46:0212735 AUTH_NONE,
12736 OK,
12737 kServer,
12738 AUTH_ASYNC,
12739 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612740 3,
asankac93076192016-10-03 15:46:0212741 kNoSSL,
12742 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612743 // The second round uses a HttpAuthHandlerMock that always succeeds.
12744 TestRound(kGet, kServerChallenge, OK),
12745 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212746 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112747 {__LINE__,
12748 kProxy,
asankac93076192016-10-03 15:46:0212749 AUTH_NONE,
12750 OK,
12751 kServer,
12752 AUTH_NONE,
12753 OK,
12754 1,
12755 kNoSSL,
12756 {TestRound(kGetProxy, kSuccess, OK)}},
12757 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112758 {__LINE__,
12759 kProxy,
asankac93076192016-10-03 15:46:0212760 AUTH_NONE,
12761 OK,
12762 kServer,
12763 AUTH_SYNC,
12764 OK,
12765 2,
12766 kNoSSL,
12767 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512768 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112769 {__LINE__,
12770 kProxy,
asankac93076192016-10-03 15:46:0212771 AUTH_NONE,
12772 OK,
12773 kServer,
12774 AUTH_SYNC,
12775 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612776 3,
asankac93076192016-10-03 15:46:0212777 kNoSSL,
12778 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612779 TestRound(kGetProxy, kServerChallenge, OK),
12780 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112781 {__LINE__,
12782 kProxy,
asankac93076192016-10-03 15:46:0212783 AUTH_NONE,
12784 OK,
12785 kServer,
12786 AUTH_ASYNC,
12787 OK,
12788 2,
12789 kNoSSL,
12790 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512791 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112792 {__LINE__,
12793 kProxy,
asankac93076192016-10-03 15:46:0212794 AUTH_NONE,
12795 OK,
12796 kServer,
12797 AUTH_ASYNC,
12798 ERR_INVALID_AUTH_CREDENTIALS,
12799 2,
12800 kNoSSL,
12801 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612802 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212803 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112804 {__LINE__,
12805 kProxy,
asankac93076192016-10-03 15:46:0212806 AUTH_SYNC,
12807 OK,
12808 kServer,
12809 AUTH_NONE,
12810 OK,
12811 2,
12812 kNoSSL,
12813 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512814 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112815 {__LINE__,
12816 kProxy,
asankac93076192016-10-03 15:46:0212817 AUTH_SYNC,
12818 ERR_INVALID_AUTH_CREDENTIALS,
12819 kServer,
12820 AUTH_NONE,
12821 OK,
12822 2,
12823 kNoSSL,
12824 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612825 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112826 {__LINE__,
12827 kProxy,
asankac93076192016-10-03 15:46:0212828 AUTH_ASYNC,
12829 OK,
12830 kServer,
12831 AUTH_NONE,
12832 OK,
12833 2,
12834 kNoSSL,
12835 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512836 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112837 {__LINE__,
12838 kProxy,
asankac93076192016-10-03 15:46:0212839 AUTH_ASYNC,
12840 ERR_INVALID_AUTH_CREDENTIALS,
12841 kServer,
12842 AUTH_NONE,
12843 OK,
12844 2,
12845 kNoSSL,
12846 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612847 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112848 {__LINE__,
12849 kProxy,
12850 AUTH_ASYNC,
12851 ERR_INVALID_AUTH_CREDENTIALS,
12852 kServer,
12853 AUTH_NONE,
12854 OK,
12855 3,
12856 kNoSSL,
12857 {TestRound(kGetProxy, kProxyChallenge, OK),
12858 TestRound(kGetProxy, kProxyChallenge, OK),
12859 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212860 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112861 {__LINE__,
12862 kProxy,
asankac93076192016-10-03 15:46:0212863 AUTH_SYNC,
12864 OK,
12865 kServer,
12866 AUTH_SYNC,
12867 OK,
12868 3,
12869 kNoSSL,
12870 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512871 TestRound(kGetProxyAuth, kServerChallenge, OK),
12872 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112873 {__LINE__,
12874 kProxy,
asankac93076192016-10-03 15:46:0212875 AUTH_SYNC,
12876 OK,
12877 kServer,
12878 AUTH_SYNC,
12879 ERR_INVALID_AUTH_CREDENTIALS,
12880 3,
12881 kNoSSL,
12882 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512883 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612884 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112885 {__LINE__,
12886 kProxy,
asankac93076192016-10-03 15:46:0212887 AUTH_ASYNC,
12888 OK,
12889 kServer,
12890 AUTH_SYNC,
12891 OK,
12892 3,
12893 kNoSSL,
12894 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512895 TestRound(kGetProxyAuth, kServerChallenge, OK),
12896 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112897 {__LINE__,
12898 kProxy,
asankac93076192016-10-03 15:46:0212899 AUTH_ASYNC,
12900 OK,
12901 kServer,
12902 AUTH_SYNC,
12903 ERR_INVALID_AUTH_CREDENTIALS,
12904 3,
12905 kNoSSL,
12906 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512907 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612908 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112909 {__LINE__,
12910 kProxy,
asankac93076192016-10-03 15:46:0212911 AUTH_SYNC,
12912 OK,
12913 kServer,
12914 AUTH_ASYNC,
12915 OK,
12916 3,
12917 kNoSSL,
12918 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512919 TestRound(kGetProxyAuth, kServerChallenge, OK),
12920 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112921 {__LINE__,
12922 kProxy,
12923 AUTH_SYNC,
12924 ERR_INVALID_AUTH_CREDENTIALS,
12925 kServer,
12926 AUTH_ASYNC,
12927 OK,
12928 4,
12929 kNoSSL,
12930 {TestRound(kGetProxy, kProxyChallenge, OK),
12931 TestRound(kGetProxy, kProxyChallenge, OK),
12932 TestRound(kGetProxyAuth, kServerChallenge, OK),
12933 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12934 {__LINE__,
12935 kProxy,
asankac93076192016-10-03 15:46:0212936 AUTH_SYNC,
12937 OK,
12938 kServer,
12939 AUTH_ASYNC,
12940 ERR_INVALID_AUTH_CREDENTIALS,
12941 3,
12942 kNoSSL,
12943 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512944 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612945 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112946 {__LINE__,
12947 kProxy,
asankac93076192016-10-03 15:46:0212948 AUTH_ASYNC,
12949 OK,
12950 kServer,
12951 AUTH_ASYNC,
12952 OK,
12953 3,
12954 kNoSSL,
12955 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512956 TestRound(kGetProxyAuth, kServerChallenge, OK),
12957 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112958 {__LINE__,
12959 kProxy,
asankac93076192016-10-03 15:46:0212960 AUTH_ASYNC,
12961 OK,
12962 kServer,
12963 AUTH_ASYNC,
12964 ERR_INVALID_AUTH_CREDENTIALS,
12965 3,
12966 kNoSSL,
12967 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512968 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612969 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112970 {__LINE__,
12971 kProxy,
12972 AUTH_ASYNC,
12973 ERR_INVALID_AUTH_CREDENTIALS,
12974 kServer,
12975 AUTH_ASYNC,
12976 ERR_INVALID_AUTH_CREDENTIALS,
12977 4,
12978 kNoSSL,
12979 {TestRound(kGetProxy, kProxyChallenge, OK),
12980 TestRound(kGetProxy, kProxyChallenge, OK),
12981 TestRound(kGetProxyAuth, kServerChallenge, OK),
12982 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212983 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112984 {__LINE__,
12985 nullptr,
asankac93076192016-10-03 15:46:0212986 AUTH_NONE,
12987 OK,
12988 kSecureServer,
12989 AUTH_NONE,
12990 OK,
12991 1,
12992 0,
12993 {TestRound(kGet, kSuccess, OK)}},
12994 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112995 {__LINE__,
12996 nullptr,
asankac93076192016-10-03 15:46:0212997 AUTH_NONE,
12998 OK,
12999 kSecureServer,
13000 AUTH_SYNC,
13001 OK,
13002 2,
13003 0,
13004 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513005 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113006 {__LINE__,
13007 nullptr,
asankac93076192016-10-03 15:46:0213008 AUTH_NONE,
13009 OK,
13010 kSecureServer,
13011 AUTH_SYNC,
13012 ERR_INVALID_AUTH_CREDENTIALS,
13013 2,
13014 0,
asankae2257db2016-10-11 22:03:1613015 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113016 {__LINE__,
13017 nullptr,
asankac93076192016-10-03 15:46:0213018 AUTH_NONE,
13019 OK,
13020 kSecureServer,
13021 AUTH_ASYNC,
13022 OK,
13023 2,
13024 0,
13025 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513026 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113027 {__LINE__,
13028 nullptr,
asankac93076192016-10-03 15:46:0213029 AUTH_NONE,
13030 OK,
13031 kSecureServer,
13032 AUTH_ASYNC,
13033 ERR_INVALID_AUTH_CREDENTIALS,
13034 2,
13035 0,
asankae2257db2016-10-11 22:03:1613036 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213037 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113038 {__LINE__,
13039 kProxy,
asankac93076192016-10-03 15:46:0213040 AUTH_NONE,
13041 OK,
13042 kSecureServer,
13043 AUTH_NONE,
13044 OK,
13045 1,
13046 0,
13047 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13048 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113049 {__LINE__,
13050 kProxy,
asankac93076192016-10-03 15:46:0213051 AUTH_NONE,
13052 OK,
13053 kSecureServer,
13054 AUTH_SYNC,
13055 OK,
13056 2,
13057 0,
13058 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513059 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113060 {__LINE__,
13061 kProxy,
asankac93076192016-10-03 15:46:0213062 AUTH_NONE,
13063 OK,
13064 kSecureServer,
13065 AUTH_SYNC,
13066 ERR_INVALID_AUTH_CREDENTIALS,
13067 2,
13068 0,
13069 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613070 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113071 {__LINE__,
13072 kProxy,
asankac93076192016-10-03 15:46:0213073 AUTH_NONE,
13074 OK,
13075 kSecureServer,
13076 AUTH_ASYNC,
13077 OK,
13078 2,
13079 0,
13080 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513081 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113082 {__LINE__,
13083 kProxy,
asankac93076192016-10-03 15:46:0213084 AUTH_NONE,
13085 OK,
13086 kSecureServer,
13087 AUTH_ASYNC,
13088 ERR_INVALID_AUTH_CREDENTIALS,
13089 2,
13090 0,
13091 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613092 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213093 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113094 {__LINE__,
13095 kProxy,
asankac93076192016-10-03 15:46:0213096 AUTH_SYNC,
13097 OK,
13098 kSecureServer,
13099 AUTH_NONE,
13100 OK,
13101 2,
13102 1,
13103 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513104 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113105 {__LINE__,
13106 kProxy,
asankac93076192016-10-03 15:46:0213107 AUTH_SYNC,
13108 ERR_INVALID_AUTH_CREDENTIALS,
13109 kSecureServer,
13110 AUTH_NONE,
13111 OK,
13112 2,
13113 kNoSSL,
13114 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613115 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113116 {__LINE__,
13117 kProxy,
asankae2257db2016-10-11 22:03:1613118 AUTH_SYNC,
13119 ERR_UNSUPPORTED_AUTH_SCHEME,
13120 kSecureServer,
13121 AUTH_NONE,
13122 OK,
13123 2,
13124 kNoSSL,
13125 {TestRound(kConnect, kProxyChallenge, OK),
13126 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113127 {__LINE__,
13128 kProxy,
asankae2257db2016-10-11 22:03:1613129 AUTH_SYNC,
13130 ERR_UNEXPECTED,
13131 kSecureServer,
13132 AUTH_NONE,
13133 OK,
13134 2,
13135 kNoSSL,
13136 {TestRound(kConnect, kProxyChallenge, OK),
13137 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113138 {__LINE__,
13139 kProxy,
asankac93076192016-10-03 15:46:0213140 AUTH_ASYNC,
13141 OK,
13142 kSecureServer,
13143 AUTH_NONE,
13144 OK,
13145 2,
13146 1,
13147 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513148 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113149 {__LINE__,
13150 kProxy,
asankac93076192016-10-03 15:46:0213151 AUTH_ASYNC,
13152 ERR_INVALID_AUTH_CREDENTIALS,
13153 kSecureServer,
13154 AUTH_NONE,
13155 OK,
13156 2,
13157 kNoSSL,
13158 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613159 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213160 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113161 {__LINE__,
13162 kProxy,
asankac93076192016-10-03 15:46:0213163 AUTH_SYNC,
13164 OK,
13165 kSecureServer,
13166 AUTH_SYNC,
13167 OK,
13168 3,
13169 1,
13170 {TestRound(kConnect, kProxyChallenge, OK),
13171 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13172 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513173 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113174 {__LINE__,
13175 kProxy,
asankac93076192016-10-03 15:46:0213176 AUTH_SYNC,
13177 OK,
13178 kSecureServer,
13179 AUTH_SYNC,
13180 ERR_INVALID_AUTH_CREDENTIALS,
13181 3,
13182 1,
13183 {TestRound(kConnect, kProxyChallenge, OK),
13184 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13185 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613186 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113187 {__LINE__,
13188 kProxy,
asankac93076192016-10-03 15:46:0213189 AUTH_ASYNC,
13190 OK,
13191 kSecureServer,
13192 AUTH_SYNC,
13193 OK,
13194 3,
13195 1,
13196 {TestRound(kConnect, kProxyChallenge, OK),
13197 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13198 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513199 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113200 {__LINE__,
13201 kProxy,
asankac93076192016-10-03 15:46:0213202 AUTH_ASYNC,
13203 OK,
13204 kSecureServer,
13205 AUTH_SYNC,
13206 ERR_INVALID_AUTH_CREDENTIALS,
13207 3,
13208 1,
13209 {TestRound(kConnect, kProxyChallenge, OK),
13210 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13211 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613212 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113213 {__LINE__,
13214 kProxy,
asankac93076192016-10-03 15:46:0213215 AUTH_SYNC,
13216 OK,
13217 kSecureServer,
13218 AUTH_ASYNC,
13219 OK,
13220 3,
13221 1,
13222 {TestRound(kConnect, kProxyChallenge, OK),
13223 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13224 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513225 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113226 {__LINE__,
13227 kProxy,
asankac93076192016-10-03 15:46:0213228 AUTH_SYNC,
13229 OK,
13230 kSecureServer,
13231 AUTH_ASYNC,
13232 ERR_INVALID_AUTH_CREDENTIALS,
13233 3,
13234 1,
13235 {TestRound(kConnect, kProxyChallenge, OK),
13236 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13237 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613238 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113239 {__LINE__,
13240 kProxy,
asankac93076192016-10-03 15:46:0213241 AUTH_ASYNC,
13242 OK,
13243 kSecureServer,
13244 AUTH_ASYNC,
13245 OK,
13246 3,
13247 1,
13248 {TestRound(kConnect, kProxyChallenge, OK),
13249 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13250 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513251 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113252 {__LINE__,
13253 kProxy,
asankac93076192016-10-03 15:46:0213254 AUTH_ASYNC,
13255 OK,
13256 kSecureServer,
13257 AUTH_ASYNC,
13258 ERR_INVALID_AUTH_CREDENTIALS,
13259 3,
13260 1,
13261 {TestRound(kConnect, kProxyChallenge, OK),
13262 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13263 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613264 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113265 {__LINE__,
13266 kProxy,
13267 AUTH_ASYNC,
13268 ERR_INVALID_AUTH_CREDENTIALS,
13269 kSecureServer,
13270 AUTH_ASYNC,
13271 ERR_INVALID_AUTH_CREDENTIALS,
13272 4,
13273 2,
13274 {TestRound(kConnect, kProxyChallenge, OK),
13275 TestRound(kConnect, kProxyChallenge, OK),
13276 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13277 &kServerChallenge),
13278 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513279 };
13280
asanka463ca4262016-11-16 02:34:3113281 for (const auto& test_config : test_configs) {
13282 SCOPED_TRACE(::testing::Message() << "Test config at "
13283 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813284 HttpAuthHandlerMock::Factory* auth_factory(
13285 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713286 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913287 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613288
13289 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513290 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113291 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813292 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13293 std::string auth_challenge = "Mock realm=proxy";
13294 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413295 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13296 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813297 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013298 empty_ssl_info, origin,
13299 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813300 auth_handler->SetGenerateExpectation(
13301 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113302 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813303 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13304 }
[email protected]044de0642010-06-17 10:42:1513305 }
13306 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013307 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513308 std::string auth_challenge = "Mock realm=server";
13309 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413310 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13311 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513312 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013313 empty_ssl_info, origin,
13314 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513315 auth_handler->SetGenerateExpectation(
13316 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113317 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813318 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613319
13320 // The second handler always succeeds. It should only be used where there
13321 // are multiple auth sessions for server auth in the same network
13322 // transaction using the same auth scheme.
13323 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913324 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613325 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13326 empty_ssl_info, origin,
13327 NetLogWithSource());
13328 second_handler->SetGenerateExpectation(true, OK);
13329 auth_factory->AddMockHandler(second_handler.release(),
13330 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513331 }
13332 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913333 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913334 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13335 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513336 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913337 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513338 }
13339
13340 HttpRequestInfo request;
13341 request.method = "GET";
13342 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1013343 request.traffic_annotation =
13344 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513345
danakj1fd259a02016-04-16 03:17:0913346 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513347
rchcb68dc62015-05-21 04:45:3613348 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13349
13350 std::vector<std::vector<MockRead>> mock_reads(1);
13351 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513352 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213353 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513354 const TestRound& read_write_round = test_config.rounds[round];
13355
13356 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613357 mock_reads.back().push_back(read_write_round.read);
13358 mock_writes.back().push_back(read_write_round.write);
13359
13360 // kProxyChallenge uses Proxy-Connection: close which means that the
13361 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413362 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613363 mock_reads.push_back(std::vector<MockRead>());
13364 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513365 }
13366
rchcb68dc62015-05-21 04:45:3613367 if (read_write_round.extra_read) {
13368 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513369 }
rchcb68dc62015-05-21 04:45:3613370 if (read_write_round.extra_write) {
13371 mock_writes.back().push_back(*read_write_round.extra_write);
13372 }
[email protected]044de0642010-06-17 10:42:1513373
13374 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513375 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713376 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513377 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613378 }
[email protected]044de0642010-06-17 10:42:1513379
danakj1fd259a02016-04-16 03:17:0913380 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613381 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913382 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413383 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813384 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613385 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213386 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613387 }
13388
mmenkecc2298e2015-12-07 18:20:1813389 // Transaction must be created after DataProviders, so it's destroyed before
13390 // they are as well.
13391 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13392
rchcb68dc62015-05-21 04:45:3613393 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213394 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613395 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513396 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113397 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513398 int rv;
13399 if (round == 0) {
tfarina42834112016-09-22 13:38:2013400 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513401 } else {
[email protected]49639fa2011-12-20 23:22:4113402 rv = trans.RestartWithAuth(
13403 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513404 }
13405 if (rv == ERR_IO_PENDING)
13406 rv = callback.WaitForResult();
13407
13408 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613409 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013410 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513411 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513412 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13413 continue;
13414 }
13415 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213416 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513417 } else {
wezca1070932016-05-26 20:30:5213418 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613419 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513420 }
13421 }
[email protected]e5ae96a2010-04-14 20:12:4513422 }
13423}
13424
bncd16676a2016-07-20 16:23:0113425TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413426 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413427 HttpAuthHandlerMock::Factory* auth_factory(
13428 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713429 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913430 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713431 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13432 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413433
13434 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13435 auth_handler->set_connection_based(true);
13436 std::string auth_challenge = "Mock realm=server";
13437 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413438 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13439 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913440 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413441 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013442 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813443 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413444
[email protected]c871bce92010-07-15 21:51:1413445 int rv = OK;
13446 const HttpResponseInfo* response = NULL;
13447 HttpRequestInfo request;
13448 request.method = "GET";
13449 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1013450 request.traffic_annotation =
13451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713452
danakj1fd259a02016-04-16 03:17:0913453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013454
13455 // Use a TCP Socket Pool with only one connection per group. This is used
13456 // to validate that the TCP socket is not released to the pool between
13457 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213458 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813459 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013460 50, // Max sockets for pool
13461 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113462 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13463 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913464 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213465 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813466 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013467
bnc691fda62016-08-12 00:43:1613468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113469 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413470
13471 const MockWrite kGet(
13472 "GET / HTTP/1.1\r\n"
13473 "Host: www.example.com\r\n"
13474 "Connection: keep-alive\r\n\r\n");
13475 const MockWrite kGetAuth(
13476 "GET / HTTP/1.1\r\n"
13477 "Host: www.example.com\r\n"
13478 "Connection: keep-alive\r\n"
13479 "Authorization: auth_token\r\n\r\n");
13480
13481 const MockRead kServerChallenge(
13482 "HTTP/1.1 401 Unauthorized\r\n"
13483 "WWW-Authenticate: Mock realm=server\r\n"
13484 "Content-Type: text/html; charset=iso-8859-1\r\n"
13485 "Content-Length: 14\r\n\r\n"
13486 "Unauthorized\r\n");
13487 const MockRead kSuccess(
13488 "HTTP/1.1 200 OK\r\n"
13489 "Content-Type: text/html; charset=iso-8859-1\r\n"
13490 "Content-Length: 3\r\n\r\n"
13491 "Yes");
13492
13493 MockWrite writes[] = {
13494 // First round
13495 kGet,
13496 // Second round
13497 kGetAuth,
13498 // Third round
13499 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013500 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013501 kGetAuth,
13502 // Competing request
13503 kGet,
[email protected]c871bce92010-07-15 21:51:1413504 };
13505 MockRead reads[] = {
13506 // First round
13507 kServerChallenge,
13508 // Second round
13509 kServerChallenge,
13510 // Third round
[email protected]eca50e122010-09-11 14:03:3013511 kServerChallenge,
13512 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413513 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013514 // Competing response
13515 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413516 };
13517 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13518 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713519 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413520
thestig9d3bb0c2015-01-24 00:49:5113521 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013522
13523 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413524 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013525 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413526 if (rv == ERR_IO_PENDING)
13527 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113528 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613529 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213530 ASSERT_TRUE(response);
13531 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813532 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113533 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13534 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413535
[email protected]7ef4cbbb2011-02-06 11:19:1013536 // In between rounds, another request comes in for the same domain.
13537 // It should not be able to grab the TCP socket that trans has already
13538 // claimed.
bnc691fda62016-08-12 00:43:1613539 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113540 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013541 rv = trans_compete.Start(&request, callback_compete.callback(),
13542 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013544 // callback_compete.WaitForResult at this point would stall forever,
13545 // since the HttpNetworkTransaction does not release the request back to
13546 // the pool until after authentication completes.
13547
13548 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413549 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613550 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413551 if (rv == ERR_IO_PENDING)
13552 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113553 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613554 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213555 ASSERT_TRUE(response);
13556 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813557 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113558 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13559 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413560
[email protected]7ef4cbbb2011-02-06 11:19:1013561 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413562 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613563 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413564 if (rv == ERR_IO_PENDING)
13565 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113566 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613567 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213568 ASSERT_TRUE(response);
13569 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813570 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113571 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13572 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013573
[email protected]7ef4cbbb2011-02-06 11:19:1013574 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013575 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613576 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013577 if (rv == ERR_IO_PENDING)
13578 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113579 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613580 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213581 ASSERT_TRUE(response);
13582 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813583 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013584
asanka463ca4262016-11-16 02:34:3113585 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13586 // auth handler should transition to a DONE state in concert with the remote
13587 // server. But that's not something we can test here with a mock handler.
13588 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13589 auth_handler->state());
13590
[email protected]7ef4cbbb2011-02-06 11:19:1013591 // Read the body since the fourth round was successful. This will also
13592 // release the socket back to the pool.
13593 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613594 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013595 if (rv == ERR_IO_PENDING)
13596 rv = callback.WaitForResult();
13597 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613598 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013599 EXPECT_EQ(0, rv);
13600 // There are still 0 idle sockets, since the trans_compete transaction
13601 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813602 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013603
13604 // The competing request can now finish. Wait for the headers and then
13605 // read the body.
13606 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113607 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613608 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013609 if (rv == ERR_IO_PENDING)
13610 rv = callback.WaitForResult();
13611 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613612 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013613 EXPECT_EQ(0, rv);
13614
13615 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813616 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413617}
13618
[email protected]65041fa2010-05-21 06:56:5313619// This tests the case that a request is issued via http instead of spdy after
13620// npn is negotiated.
bncd16676a2016-07-20 16:23:0113621TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313622 HttpRequestInfo request;
13623 request.method = "GET";
bncce36dca22015-04-21 22:11:2313624 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013625 request.traffic_annotation =
13626 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313627
13628 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313629 MockWrite(
13630 "GET / HTTP/1.1\r\n"
13631 "Host: www.example.org\r\n"
13632 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313633 };
13634
13635 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213636 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313637 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213638 MockRead("\r\n"),
13639 MockRead("hello world"),
13640 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313641 };
13642
[email protected]8ddf8322012-02-23 18:08:0613643 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613644 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313645
[email protected]bb88e1d32013-05-03 23:11:0713646 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313647
13648 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13649 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713650 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313651
[email protected]49639fa2011-12-20 23:22:4113652 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313653
danakj1fd259a02016-04-16 03:17:0913654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313656
tfarina42834112016-09-22 13:38:2013657 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313658
robpercival214763f2016-07-01 23:27:0113659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13660 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313661
bnc691fda62016-08-12 00:43:1613662 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213663 ASSERT_TRUE(response);
13664 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313665 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13666
13667 std::string response_data;
bnc691fda62016-08-12 00:43:1613668 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313669 EXPECT_EQ("hello world", response_data);
13670
13671 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213672 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313673}
[email protected]26ef6582010-06-24 02:30:4713674
bnc55ff9da2015-08-19 18:42:3513675// Simulate the SSL handshake completing with an NPN negotiation followed by an
13676// immediate server closing of the socket.
13677// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113678TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713679 HttpRequestInfo request;
13680 request.method = "GET";
bncce36dca22015-04-21 22:11:2313681 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013682 request.traffic_annotation =
13683 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713684
[email protected]8ddf8322012-02-23 18:08:0613685 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613686 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713688
Bence Béky27ad0a12018-02-08 00:35:4813689 SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113690 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713691
13692 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613693 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713694 };
13695
rch8e6c6c42015-05-01 14:05:1313696 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13697 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713698 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713699
[email protected]49639fa2011-12-20 23:22:4113700 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713701
danakj1fd259a02016-04-16 03:17:0913702 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713704
tfarina42834112016-09-22 13:38:2013705 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13707 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713708}
[email protected]65d34382010-07-01 18:12:2613709
[email protected]795cbf82013-07-22 09:37:2713710// A subclass of HttpAuthHandlerMock that records the request URL when
13711// it gets it. This is needed since the auth handler may get destroyed
13712// before we get a chance to query it.
13713class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13714 public:
13715 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13716
Chris Watkins7a41d3552017-12-01 02:13:2713717 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713718
13719 protected:
dchengb03027d2014-10-21 12:00:2013720 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13721 const HttpRequestInfo* request,
13722 const CompletionCallback& callback,
13723 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713724 *url_ = request->url;
13725 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13726 credentials, request, callback, auth_token);
13727 }
13728
13729 private:
13730 GURL* url_;
13731};
13732
[email protected]8e6441ca2010-08-19 05:56:3813733// Test that if we cancel the transaction as the connection is completing, that
13734// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113735TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813736 // Setup everything about the connection to complete synchronously, so that
13737 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13738 // for is the callback from the HttpStreamRequest.
13739 // Then cancel the transaction.
13740 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613741 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813742 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613743 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13744 MockRead(SYNCHRONOUS, "hello world"),
13745 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813746 };
13747
[email protected]8e6441ca2010-08-19 05:56:3813748 HttpRequestInfo request;
13749 request.method = "GET";
bncce36dca22015-04-21 22:11:2313750 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013751 request.traffic_annotation =
13752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813753
[email protected]bb88e1d32013-05-03 23:11:0713754 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813756 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913757 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713758
[email protected]8e6441ca2010-08-19 05:56:3813759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13760 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713761 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813762
[email protected]49639fa2011-12-20 23:22:4113763 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813764
vishal.b62985ca92015-04-17 08:45:5113765 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113766 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813768 trans.reset(); // Cancel the transaction here.
13769
fdoray92e35a72016-06-10 15:54:5513770 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013771}
13772
[email protected]ecab6e052014-05-16 14:58:1213773// Test that if a transaction is cancelled after receiving the headers, the
13774// stream is drained properly and added back to the socket pool. The main
13775// purpose of this test is to make sure that an HttpStreamParser can be read
13776// from after the HttpNetworkTransaction and the objects it owns have been
13777// deleted.
13778// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113779TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213780 MockRead data_reads[] = {
13781 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13782 MockRead(ASYNC, "Content-Length: 2\r\n"),
13783 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13784 MockRead(ASYNC, "1"),
13785 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13786 // HttpNetworkTransaction has been deleted.
13787 MockRead(ASYNC, "2"),
13788 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13789 };
13790 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13791 session_deps_.socket_factory->AddSocketDataProvider(&data);
13792
danakj1fd259a02016-04-16 03:17:0913793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213794
13795 {
13796 HttpRequestInfo request;
13797 request.method = "GET";
bncce36dca22015-04-21 22:11:2313798 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013799 request.traffic_annotation =
13800 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213801
dcheng48459ac22014-08-26 00:46:4113802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213803 TestCompletionCallback callback;
13804
tfarina42834112016-09-22 13:38:2013805 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213807 callback.WaitForResult();
13808
13809 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213810 ASSERT_TRUE(response);
13811 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213812 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13813
13814 // The transaction and HttpRequestInfo are deleted.
13815 }
13816
13817 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513818 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213819
13820 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113821 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213822}
13823
[email protected]76a505b2010-08-25 06:23:0013824// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113825TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913826 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913827 ProxyResolutionService::CreateFixedFromPacResult(
13828 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113829 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713830 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013832
[email protected]76a505b2010-08-25 06:23:0013833 HttpRequestInfo request;
13834 request.method = "GET";
bncce36dca22015-04-21 22:11:2313835 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013836 request.traffic_annotation =
13837 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013838
13839 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313840 MockWrite(
13841 "GET http://www.example.org/ HTTP/1.1\r\n"
13842 "Host: www.example.org\r\n"
13843 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013844 };
13845
13846 MockRead data_reads1[] = {
13847 MockRead("HTTP/1.1 200 OK\r\n"),
13848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13849 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613850 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013851 };
13852
13853 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13854 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713855 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013856
[email protected]49639fa2011-12-20 23:22:4113857 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013858
bnc691fda62016-08-12 00:43:1613859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913860 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613861 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913862 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13863 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013864
bnc691fda62016-08-12 00:43:1613865 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013867
13868 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113869 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013870
bnc691fda62016-08-12 00:43:1613871 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213872 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013873
13874 EXPECT_TRUE(response->headers->IsKeepAlive());
13875 EXPECT_EQ(200, response->headers->response_code());
13876 EXPECT_EQ(100, response->headers->GetContentLength());
13877 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713878 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13879 HostPortPair::FromString("myproxy:70")),
13880 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913881 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13882 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13883 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013884 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013885
13886 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613887 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013888 TestLoadTimingNotReusedWithPac(load_timing_info,
13889 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013890}
13891
13892// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113893TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913894 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913895 ProxyResolutionService::CreateFixedFromPacResult(
13896 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113897 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713898 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913899 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013900
[email protected]76a505b2010-08-25 06:23:0013901 HttpRequestInfo request;
13902 request.method = "GET";
bncce36dca22015-04-21 22:11:2313903 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013904 request.traffic_annotation =
13905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013906
13907 // Since we have proxy, should try to establish tunnel.
13908 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713909 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13910 "Host: www.example.org:443\r\n"
13911 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013912
rsleevidb16bb02015-11-12 23:47:1713913 MockWrite("GET / HTTP/1.1\r\n"
13914 "Host: www.example.org\r\n"
13915 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013916 };
13917
13918 MockRead data_reads1[] = {
13919 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13920
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]8ddf8322012-02-23 18:08:0613930 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713931 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013932
[email protected]49639fa2011-12-20 23:22:4113933 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013934
bnc691fda62016-08-12 00:43:1613935 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913936 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613937 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913938 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13939 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013940
bnc691fda62016-08-12 00:43:1613941 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013943
13944 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113945 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613946 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013947 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013948 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013949 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13950 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013951 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013952 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013953 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13954 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013955
bnc691fda62016-08-12 00:43:1613956 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213957 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013958
13959 EXPECT_TRUE(response->headers->IsKeepAlive());
13960 EXPECT_EQ(200, response->headers->response_code());
13961 EXPECT_EQ(100, response->headers->GetContentLength());
13962 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13963 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713964 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13965 HostPortPair::FromString("myproxy:70")),
13966 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913967 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13968 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13969 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013970
13971 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613972 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013973 TestLoadTimingNotReusedWithPac(load_timing_info,
13974 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013975}
13976
rsleevidb16bb02015-11-12 23:47:1713977// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13978// literal host.
bncd16676a2016-07-20 16:23:0113979TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913980 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913981 ProxyResolutionService::CreateFixedFromPacResult(
13982 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713983 BoundTestNetLog log;
13984 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913985 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713986
13987 HttpRequestInfo request;
13988 request.method = "GET";
13989 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1013990 request.traffic_annotation =
13991 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713992
13993 // Since we have proxy, should try to establish tunnel.
13994 MockWrite data_writes1[] = {
13995 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13996 "Host: [::1]:443\r\n"
13997 "Proxy-Connection: keep-alive\r\n\r\n"),
13998
13999 MockWrite("GET / HTTP/1.1\r\n"
14000 "Host: [::1]\r\n"
14001 "Connection: keep-alive\r\n\r\n"),
14002 };
14003
14004 MockRead data_reads1[] = {
14005 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14006
14007 MockRead("HTTP/1.1 200 OK\r\n"),
14008 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14009 MockRead("Content-Length: 100\r\n\r\n"),
14010 MockRead(SYNCHRONOUS, OK),
14011 };
14012
14013 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14014 data_writes1, arraysize(data_writes1));
14015 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14016 SSLSocketDataProvider ssl(ASYNC, OK);
14017 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14018
14019 TestCompletionCallback callback1;
14020
bnc691fda62016-08-12 00:43:1614021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714022
bnc691fda62016-08-12 00:43:1614023 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714025
14026 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114027 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714028 TestNetLogEntry::List entries;
14029 log.GetEntries(&entries);
14030 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014031 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14032 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714033 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014034 entries, pos,
14035 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14036 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714037
bnc691fda62016-08-12 00:43:1614038 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214039 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714040
14041 EXPECT_TRUE(response->headers->IsKeepAlive());
14042 EXPECT_EQ(200, response->headers->response_code());
14043 EXPECT_EQ(100, response->headers->GetContentLength());
14044 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14045 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714046 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14047 HostPortPair::FromString("myproxy:70")),
14048 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714049
14050 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614051 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714052 TestLoadTimingNotReusedWithPac(load_timing_info,
14053 CONNECT_TIMING_HAS_SSL_TIMES);
14054}
14055
[email protected]76a505b2010-08-25 06:23:0014056// Test a basic HTTPS GET request through a proxy, but the server hangs up
14057// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114058TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914059 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14060 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114061 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714062 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914063 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014064
[email protected]76a505b2010-08-25 06:23:0014065 HttpRequestInfo request;
14066 request.method = "GET";
bncce36dca22015-04-21 22:11:2314067 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014068 request.traffic_annotation =
14069 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014070
14071 // Since we have proxy, should try to establish tunnel.
14072 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714073 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14074 "Host: www.example.org:443\r\n"
14075 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014076
rsleevidb16bb02015-11-12 23:47:1714077 MockWrite("GET / HTTP/1.1\r\n"
14078 "Host: www.example.org\r\n"
14079 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014080 };
14081
14082 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014083 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614084 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014085 };
14086
14087 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14088 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714089 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614090 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014092
[email protected]49639fa2011-12-20 23:22:4114093 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014094
bnc691fda62016-08-12 00:43:1614095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014096
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));
[email protected]76a505b2010-08-25 06:23:0014099
14100 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114101 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614102 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014103 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014104 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014105 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14106 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014107 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014108 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014109 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14110 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014111}
14112
[email protected]749eefa82010-09-13 22:14:0314113// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114114TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114115 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914116 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114117 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314118
bnc42331402016-07-25 13:36:1514119 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114120 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314121 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114122 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314123 };
14124
rch8e6c6c42015-05-01 14:05:1314125 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
14126 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714127 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314128
[email protected]8ddf8322012-02-23 18:08:0614129 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614130 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314132
danakj1fd259a02016-04-16 03:17:0914133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314134
14135 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314136 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014137 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414138 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714139 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214140 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314141
14142 HttpRequestInfo request;
14143 request.method = "GET";
bncce36dca22015-04-21 22:11:2314144 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014145 request.traffic_annotation =
14146 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314147
14148 // This is the important line that marks this as a preconnect.
14149 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14150
bnc691fda62016-08-12 00:43:1614151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314152
[email protected]41d64e82013-07-03 22:44:2614153 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014154 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14156 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314157}
14158
[email protected]73b8dd222010-11-11 19:55:2414159// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614160// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214161void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714162 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914163 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714164 request_info.url = GURL("https://www.example.com/");
14165 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914166 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014167 request_info.traffic_annotation =
14168 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714169
[email protected]8ddf8322012-02-23 18:08:0614170 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914171 MockWrite data_writes[] = {
14172 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414173 };
ttuttle859dc7a2015-04-23 19:42:2914174 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0714175 session_deps_.socket_factory->AddSocketDataProvider(&data);
14176 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414177
danakj1fd259a02016-04-16 03:17:0914178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614179 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414180
[email protected]49639fa2011-12-20 23:22:4114181 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014182 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914183 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414184 rv = callback.WaitForResult();
14185 ASSERT_EQ(error, rv);
14186}
14187
bncd16676a2016-07-20 16:23:0114188TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414189 // Just check a grab bag of cert errors.
14190 static const int kErrors[] = {
14191 ERR_CERT_COMMON_NAME_INVALID,
14192 ERR_CERT_AUTHORITY_INVALID,
14193 ERR_CERT_DATE_INVALID,
14194 };
14195 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614196 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14197 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414198 }
14199}
14200
[email protected]bd0b6772011-01-11 19:59:3014201// Ensure that a client certificate is removed from the SSL client auth
14202// cache when:
14203// 1) No proxy is involved.
14204// 2) TLS False Start is disabled.
14205// 3) The initial TLS handshake requests a client certificate.
14206// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114207TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914208 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714209 request_info.url = GURL("https://www.example.com/");
14210 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914211 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014212 request_info.traffic_annotation =
14213 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714214
[email protected]bd0b6772011-01-11 19:59:3014215 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114216 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014217
14218 // [ssl_]data1 contains the data for the first SSL handshake. When a
14219 // CertificateRequest is received for the first time, the handshake will
14220 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914221 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014222 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914224 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714225 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014226
14227 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14228 // False Start is not being used, the result of the SSL handshake will be
14229 // returned as part of the SSLClientSocket::Connect() call. This test
14230 // matches the result of a server sending a handshake_failure alert,
14231 // rather than a Finished message, because it requires a client
14232 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914233 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014234 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714235 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914236 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714237 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014238
14239 // [ssl_]data3 contains the data for the third SSL handshake. When a
14240 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214241 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14242 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014243 // of the HttpNetworkTransaction. Because this test failure is due to
14244 // requiring a client certificate, this fallback handshake should also
14245 // fail.
ttuttle859dc7a2015-04-23 19:42:2914246 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014247 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714248 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914249 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714250 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014251
[email protected]80c75f682012-05-26 16:22:1714252 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14253 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214254 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14255 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714256 // of the HttpNetworkTransaction. Because this test failure is due to
14257 // requiring a client certificate, this fallback handshake should also
14258 // fail.
ttuttle859dc7a2015-04-23 19:42:2914259 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714260 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914262 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714263 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714264
danakj1fd259a02016-04-16 03:17:0914265 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614266 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014267
[email protected]bd0b6772011-01-11 19:59:3014268 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114269 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014270 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114271 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014272
14273 // Complete the SSL handshake, which should abort due to requiring a
14274 // client certificate.
14275 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114276 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014277
14278 // Indicate that no certificate should be supplied. From the perspective
14279 // of SSLClientCertCache, NULL is just as meaningful as a real
14280 // certificate, so this is the same as supply a
14281 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614282 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114283 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014284
14285 // Ensure the certificate was added to the client auth cache before
14286 // allowing the connection to continue restarting.
14287 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414288 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114289 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414290 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214291 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014292
14293 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714294 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14295 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014296 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114297 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014298
14299 // Ensure that the client certificate is removed from the cache on a
14300 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114301 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414302 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014303}
14304
14305// Ensure that a client certificate is removed from the SSL client auth
14306// cache when:
14307// 1) No proxy is involved.
14308// 2) TLS False Start is enabled.
14309// 3) The initial TLS handshake requests a client certificate.
14310// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114311TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914312 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714313 request_info.url = GURL("https://www.example.com/");
14314 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914315 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014316 request_info.traffic_annotation =
14317 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714318
[email protected]bd0b6772011-01-11 19:59:3014319 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114320 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014321
14322 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14323 // return successfully after reading up to the peer's Certificate message.
14324 // This is to allow the caller to call SSLClientSocket::Write(), which can
14325 // enqueue application data to be sent in the same packet as the
14326 // ChangeCipherSpec and Finished messages.
14327 // The actual handshake will be finished when SSLClientSocket::Read() is
14328 // called, which expects to process the peer's ChangeCipherSpec and
14329 // Finished messages. If there was an error negotiating with the peer,
14330 // such as due to the peer requiring a client certificate when none was
14331 // supplied, the alert sent by the peer won't be processed until Read() is
14332 // called.
14333
14334 // Like the non-False Start case, when a client certificate is requested by
14335 // the peer, the handshake is aborted during the Connect() call.
14336 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914337 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014338 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914340 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014342
14343 // When a client certificate is supplied, Connect() will not be aborted
14344 // when the peer requests the certificate. Instead, the handshake will
14345 // artificially succeed, allowing the caller to write the HTTP request to
14346 // the socket. The handshake messages are not processed until Read() is
14347 // called, which then detects that the handshake was aborted, due to the
14348 // peer sending a handshake_failure because it requires a client
14349 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914350 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014351 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914353 MockRead data2_reads[] = {
14354 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014355 };
ttuttle859dc7a2015-04-23 19:42:2914356 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714357 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014358
14359 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714360 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14361 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914362 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014363 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914365 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714366 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014367
[email protected]80c75f682012-05-26 16:22:1714368 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14369 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914370 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714371 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914373 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714374 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714375
[email protected]7799de12013-05-30 05:52:5114376 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914377 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114378 ssl_data5.cert_request_info = cert_request.get();
14379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914380 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114381 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14382
danakj1fd259a02016-04-16 03:17:0914383 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614384 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014385
[email protected]bd0b6772011-01-11 19:59:3014386 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114387 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014388 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114389 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014390
14391 // Complete the SSL handshake, which should abort due to requiring a
14392 // client certificate.
14393 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114394 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014395
14396 // Indicate that no certificate should be supplied. From the perspective
14397 // of SSLClientCertCache, NULL is just as meaningful as a real
14398 // certificate, so this is the same as supply a
14399 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614400 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114401 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014402
14403 // Ensure the certificate was added to the client auth cache before
14404 // allowing the connection to continue restarting.
14405 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414406 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114407 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414408 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214409 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014410
[email protected]bd0b6772011-01-11 19:59:3014411 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714412 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14413 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014414 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114415 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014416
14417 // Ensure that the client certificate is removed from the cache on a
14418 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114419 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414420 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014421}
14422
[email protected]8c405132011-01-11 22:03:1814423// Ensure that a client certificate is removed from the SSL client auth
14424// cache when:
14425// 1) An HTTPS proxy is involved.
14426// 3) The HTTPS proxy requests a client certificate.
14427// 4) The client supplies an invalid/unacceptable certificate for the
14428// proxy.
14429// The test is repeated twice, first for connecting to an HTTPS endpoint,
14430// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114431TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914432 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14433 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114434 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714435 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814436
14437 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114438 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814439
14440 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14441 // [ssl_]data[1-3]. Rather than represending the endpoint
14442 // (www.example.com:443), they represent failures with the HTTPS proxy
14443 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914444 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814445 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914447 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714448 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814449
ttuttle859dc7a2015-04-23 19:42:2914450 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814451 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914453 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714454 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814455
[email protected]80c75f682012-05-26 16:22:1714456 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14457#if 0
ttuttle859dc7a2015-04-23 19:42:2914458 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814459 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914461 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714462 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714463#endif
[email protected]8c405132011-01-11 22:03:1814464
ttuttle859dc7a2015-04-23 19:42:2914465 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814466 requests[0].url = GURL("https://www.example.com/");
14467 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914468 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014469 requests[0].traffic_annotation =
14470 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814471
14472 requests[1].url = GURL("http://www.example.com/");
14473 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914474 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014475 requests[1].traffic_annotation =
14476 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814477
14478 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714479 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814482
14483 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114484 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014485 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114486 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814487
14488 // Complete the SSL handshake, which should abort due to requiring a
14489 // client certificate.
14490 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114491 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814492
14493 // Indicate that no certificate should be supplied. From the perspective
14494 // of SSLClientCertCache, NULL is just as meaningful as a real
14495 // certificate, so this is the same as supply a
14496 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614497 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114498 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814499
14500 // Ensure the certificate was added to the client auth cache before
14501 // allowing the connection to continue restarting.
14502 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414503 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114504 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414505 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214506 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814507 // Ensure the certificate was NOT cached for the endpoint. This only
14508 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114509 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414510 HostPortPair("www.example.com", 443), &client_cert,
14511 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814512
14513 // Restart the handshake. This will consume ssl_data2, which fails, and
14514 // then consume ssl_data3, which should also fail. The result code is
14515 // checked against what ssl_data3 should return.
14516 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114517 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814518
14519 // Now that the new handshake has failed, ensure that the client
14520 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114521 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414522 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114523 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414524 HostPortPair("www.example.com", 443), &client_cert,
14525 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814526 }
14527}
14528
bncd16676a2016-07-20 16:23:0114529TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614530 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914531 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914532 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614533
bnc032658ba2016-09-26 18:17:1514534 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614535
bncdf80d44fd2016-07-15 20:27:4114536 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914537 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814538 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114539 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714540 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614541 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114542 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614543 };
bnc42331402016-07-25 13:36:1514544 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114545 SpdySerializedFrame host1_resp_body(
14546 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514547 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114548 SpdySerializedFrame host2_resp_body(
14549 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614550 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114551 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14552 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314553 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614554 };
14555
eroman36d84e54432016-03-17 03:23:0214556 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214557 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314558 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14559 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714560 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614561
[email protected]aa22b242011-11-16 18:58:2914562 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614563 HttpRequestInfo request1;
14564 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314565 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614566 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014567 request1.traffic_annotation =
14568 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014569 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614570
tfarina42834112016-09-22 13:38:2014571 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14573 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614574
14575 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214576 ASSERT_TRUE(response);
14577 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214578 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614579
14580 std::string response_data;
robpercival214763f2016-07-01 23:27:0114581 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614582 EXPECT_EQ("hello!", response_data);
14583
bnca4d611d2016-09-22 19:55:3714584 // Preload mail.example.com into HostCache.
14585 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014586 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614587 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014588 std::unique_ptr<HostResolver::Request> request;
14589 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14590 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014591 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714593 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114594 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614595
14596 HttpRequestInfo request2;
14597 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714598 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614599 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014600 request2.traffic_annotation =
14601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014602 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614603
tfarina42834112016-09-22 13:38:2014604 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14606 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614607
14608 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214609 ASSERT_TRUE(response);
14610 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214611 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614612 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214613 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114614 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614615 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614616}
14617
bncd16676a2016-07-20 16:23:0114618TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214619 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914620 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214622
bnc032658ba2016-09-26 18:17:1514623 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214624
bncdf80d44fd2016-07-15 20:27:4114625 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914626 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814627 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114628 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714629 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214630 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114631 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214632 };
bnc42331402016-07-25 13:36:1514633 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114634 SpdySerializedFrame host1_resp_body(
14635 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514636 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114637 SpdySerializedFrame host2_resp_body(
14638 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214639 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114640 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14641 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314642 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214643 };
14644
eroman36d84e54432016-03-17 03:23:0214645 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214646 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314647 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14648 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714649 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214650
14651 TestCompletionCallback callback;
14652 HttpRequestInfo request1;
14653 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314654 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214655 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014656 request1.traffic_annotation =
14657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014658 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214659
tfarina42834112016-09-22 13:38:2014660 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14662 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214663
14664 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214665 ASSERT_TRUE(response);
14666 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214667 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214668
14669 std::string response_data;
robpercival214763f2016-07-01 23:27:0114670 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214671 EXPECT_EQ("hello!", response_data);
14672
14673 HttpRequestInfo request2;
14674 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714675 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214676 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014677 request2.traffic_annotation =
14678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014679 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214680
tfarina42834112016-09-22 13:38:2014681 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114682 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14683 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214684
14685 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214686 ASSERT_TRUE(response);
14687 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214688 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214689 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214690 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114691 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214692 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214693}
14694
bnc8016c1f2017-03-31 02:11:2914695// Regression test for https://crbug.com/546991.
14696// The server might not be able to serve an IP pooled request, and might send a
14697// 421 Misdirected Request response status to indicate this.
14698// HttpNetworkTransaction should reset the request and retry without IP pooling.
14699TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14700 // Two hosts resolve to the same IP address.
14701 const std::string ip_addr = "1.2.3.4";
14702 IPAddress ip;
14703 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14704 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14705
Jeremy Roman0579ed62017-08-29 15:56:1914706 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914707 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14708 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14709
14710 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14711
14712 // Two requests on the first connection.
14713 SpdySerializedFrame req1(
14714 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14715 spdy_util_.UpdateWithStreamDestruction(1);
14716 SpdySerializedFrame req2(
14717 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14718 SpdySerializedFrame rst(
14719 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14720 MockWrite writes1[] = {
14721 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14722 CreateMockWrite(rst, 6),
14723 };
14724
14725 // The first one succeeds, the second gets error 421 Misdirected Request.
14726 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14727 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14728 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714729 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914730 SpdySerializedFrame resp2(
14731 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14732 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14733 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14734
14735 MockConnect connect1(ASYNC, OK, peer_addr);
14736 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14737 arraysize(writes1));
14738 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14739
14740 AddSSLSocketData();
14741
14742 // Retry the second request on a second connection.
14743 SpdyTestUtil spdy_util2;
14744 SpdySerializedFrame req3(
14745 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14746 MockWrite writes2[] = {
14747 CreateMockWrite(req3, 0),
14748 };
14749
14750 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14751 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14752 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14753 MockRead(ASYNC, 0, 3)};
14754
14755 MockConnect connect2(ASYNC, OK, peer_addr);
14756 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14757 arraysize(writes2));
14758 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14759
14760 AddSSLSocketData();
14761
14762 // Preload mail.example.org into HostCache.
14763 HostPortPair host_port("mail.example.org", 443);
14764 HostResolver::RequestInfo resolve_info(host_port);
14765 AddressList ignored;
14766 std::unique_ptr<HostResolver::Request> request;
14767 TestCompletionCallback callback;
14768 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14769 &ignored, callback.callback(),
14770 &request, NetLogWithSource());
14771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14772 rv = callback.WaitForResult();
14773 EXPECT_THAT(rv, IsOk());
14774
14775 HttpRequestInfo request1;
14776 request1.method = "GET";
14777 request1.url = GURL("https://www.example.org/");
14778 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014779 request1.traffic_annotation =
14780 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914781 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14782
14783 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14785 rv = callback.WaitForResult();
14786 EXPECT_THAT(rv, IsOk());
14787
14788 const HttpResponseInfo* response = trans1.GetResponseInfo();
14789 ASSERT_TRUE(response);
14790 ASSERT_TRUE(response->headers);
14791 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14792 EXPECT_TRUE(response->was_fetched_via_spdy);
14793 EXPECT_TRUE(response->was_alpn_negotiated);
14794 std::string response_data;
14795 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14796 EXPECT_EQ("hello!", response_data);
14797
14798 HttpRequestInfo request2;
14799 request2.method = "GET";
14800 request2.url = GURL("https://mail.example.org/");
14801 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014802 request2.traffic_annotation =
14803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914804 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14805
14806 BoundTestNetLog log;
14807 rv = trans2.Start(&request2, callback.callback(), log.bound());
14808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14809 rv = callback.WaitForResult();
14810 EXPECT_THAT(rv, IsOk());
14811
14812 response = trans2.GetResponseInfo();
14813 ASSERT_TRUE(response);
14814 ASSERT_TRUE(response->headers);
14815 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14816 EXPECT_TRUE(response->was_fetched_via_spdy);
14817 EXPECT_TRUE(response->was_alpn_negotiated);
14818 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14819 EXPECT_EQ("hello!", response_data);
14820
14821 TestNetLogEntry::List entries;
14822 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914823 ExpectLogContainsSomewhere(
14824 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914825 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914826}
14827
14828// Test that HTTP 421 responses are properly returned to the caller if received
14829// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14830// portions of the response.
14831TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14832 // Two hosts resolve to the same IP address.
14833 const std::string ip_addr = "1.2.3.4";
14834 IPAddress ip;
14835 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14836 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14837
Jeremy Roman0579ed62017-08-29 15:56:1914838 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914839 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14840 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14841
14842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14843
14844 // Two requests on the first connection.
14845 SpdySerializedFrame req1(
14846 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14847 spdy_util_.UpdateWithStreamDestruction(1);
14848 SpdySerializedFrame req2(
14849 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14850 SpdySerializedFrame rst(
14851 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14852 MockWrite writes1[] = {
14853 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14854 CreateMockWrite(rst, 6),
14855 };
14856
14857 // The first one succeeds, the second gets error 421 Misdirected Request.
14858 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14859 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14860 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714861 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914862 SpdySerializedFrame resp2(
14863 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14864 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14865 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14866
14867 MockConnect connect1(ASYNC, OK, peer_addr);
14868 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14869 arraysize(writes1));
14870 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14871
14872 AddSSLSocketData();
14873
14874 // Retry the second request on a second connection. It returns 421 Misdirected
14875 // Retry again.
14876 SpdyTestUtil spdy_util2;
14877 SpdySerializedFrame req3(
14878 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14879 MockWrite writes2[] = {
14880 CreateMockWrite(req3, 0),
14881 };
14882
14883 SpdySerializedFrame resp3(
14884 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14885 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14886 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14887 MockRead(ASYNC, 0, 3)};
14888
14889 MockConnect connect2(ASYNC, OK, peer_addr);
14890 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14891 arraysize(writes2));
14892 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14893
14894 AddSSLSocketData();
14895
14896 // Preload mail.example.org into HostCache.
14897 HostPortPair host_port("mail.example.org", 443);
14898 HostResolver::RequestInfo resolve_info(host_port);
14899 AddressList ignored;
14900 std::unique_ptr<HostResolver::Request> request;
14901 TestCompletionCallback callback;
14902 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14903 &ignored, callback.callback(),
14904 &request, NetLogWithSource());
14905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14906 rv = callback.WaitForResult();
14907 EXPECT_THAT(rv, IsOk());
14908
14909 HttpRequestInfo request1;
14910 request1.method = "GET";
14911 request1.url = GURL("https://www.example.org/");
14912 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014913 request1.traffic_annotation =
14914 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914915 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14916
14917 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14919 rv = callback.WaitForResult();
14920 EXPECT_THAT(rv, IsOk());
14921
14922 const HttpResponseInfo* response = trans1.GetResponseInfo();
14923 ASSERT_TRUE(response);
14924 ASSERT_TRUE(response->headers);
14925 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14926 EXPECT_TRUE(response->was_fetched_via_spdy);
14927 EXPECT_TRUE(response->was_alpn_negotiated);
14928 std::string response_data;
14929 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14930 EXPECT_EQ("hello!", response_data);
14931
14932 HttpRequestInfo request2;
14933 request2.method = "GET";
14934 request2.url = GURL("https://mail.example.org/");
14935 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014936 request2.traffic_annotation =
14937 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914938 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14939
14940 BoundTestNetLog log;
14941 rv = trans2.Start(&request2, callback.callback(), log.bound());
14942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14943 rv = callback.WaitForResult();
14944 EXPECT_THAT(rv, IsOk());
14945
14946 // After a retry, the 421 Misdirected Request is reported back up to the
14947 // caller.
14948 response = trans2.GetResponseInfo();
14949 ASSERT_TRUE(response);
14950 ASSERT_TRUE(response->headers);
14951 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14952 EXPECT_TRUE(response->was_fetched_via_spdy);
14953 EXPECT_TRUE(response->was_alpn_negotiated);
14954 EXPECT_TRUE(response->ssl_info.cert);
14955 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14956 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914957}
14958
bnc6dcd8192017-05-25 20:11:5014959class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614960 public:
14961 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014962 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714963 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614964
dchengb03027d2014-10-21 12:00:2014965 int ResolveFromCache(const RequestInfo& info,
14966 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014967 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014968 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014969 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014970 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614971 return rv;
14972 }
14973
[email protected]e3ceb682011-06-28 23:55:4614974 private:
[email protected]e3ceb682011-06-28 23:55:4614975 const HostPortPair host_port_;
14976};
14977
bncd16676a2016-07-20 16:23:0114978TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314979 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614980 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914981 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714982 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614984
bnc032658ba2016-09-26 18:17:1514985 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614986
bncdf80d44fd2016-07-15 20:27:4114987 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914988 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814989 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114990 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714991 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614992 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114993 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614994 };
bnc42331402016-07-25 13:36:1514995 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114996 SpdySerializedFrame host1_resp_body(
14997 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514998 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114999 SpdySerializedFrame host2_resp_body(
15000 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615001 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115002 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15003 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315004 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615005 };
15006
eroman36d84e54432016-03-17 03:23:0215007 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215008 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1315009 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
15010 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0715011 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615012
[email protected]aa22b242011-11-16 18:58:2915013 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615014 HttpRequestInfo request1;
15015 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315016 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615017 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015018 request1.traffic_annotation =
15019 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015020 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615021
tfarina42834112016-09-22 13:38:2015022 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15024 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615025
15026 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215027 ASSERT_TRUE(response);
15028 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215029 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615030
15031 std::string response_data;
robpercival214763f2016-07-01 23:27:0115032 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615033 EXPECT_EQ("hello!", response_data);
15034
15035 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715036 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615037 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015038 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015039 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15040 &ignored, callback.callback(),
15041 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715043 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115044 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615045
15046 HttpRequestInfo request2;
15047 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715048 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615049 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015050 request2.traffic_annotation =
15051 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015052 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615053
tfarina42834112016-09-22 13:38:2015054 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15056 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615057
15058 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215059 ASSERT_TRUE(response);
15060 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215061 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615062 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215063 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115064 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615065 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615066}
15067
bncd16676a2016-07-20 16:23:0115068TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315069 const std::string https_url = "https://www.example.org:8080/";
15070 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415071
15072 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115073 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915074 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415075
15076 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115077 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415078 };
15079
bnc42331402016-07-25 13:36:1515080 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115081 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15082 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915083 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415084
rch8e6c6c42015-05-01 14:05:1315085 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15086 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415087 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715088 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415089
15090 // HTTP GET for the HTTP URL
15091 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315092 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415093 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315094 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415095 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415096 };
15097
15098 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315099 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15100 MockRead(ASYNC, 2, "hello"),
15101 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415102 };
15103
rch8e6c6c42015-05-01 14:05:1315104 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15105 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0415106
[email protected]8450d722012-07-02 19:14:0415107 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615108 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715109 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15110 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15111 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415112
danakj1fd259a02016-04-16 03:17:0915113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415114
15115 // Start the first transaction to set up the SpdySession
15116 HttpRequestInfo request1;
15117 request1.method = "GET";
15118 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415119 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015120 request1.traffic_annotation =
15121 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015122 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415123 TestCompletionCallback callback1;
15124 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015125 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515126 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415127
robpercival214763f2016-07-01 23:27:0115128 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415129 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15130
15131 // Now, start the HTTP request
15132 HttpRequestInfo request2;
15133 request2.method = "GET";
15134 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415135 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015136 request2.traffic_annotation =
15137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015138 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415139 TestCompletionCallback callback2;
15140 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015141 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515142 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415143
robpercival214763f2016-07-01 23:27:0115144 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415145 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15146}
15147
bnc5452e2a2015-05-08 16:27:4215148// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15149// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115150TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515151 url::SchemeHostPort server("https", "www.example.org", 443);
15152 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215153
bnc8bef8da22016-05-30 01:28:2515154 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215155 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615156 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215157 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15158
15159 // No data should be read from the alternative, because HTTP/1.1 is
15160 // negotiated.
15161 StaticSocketDataProvider data;
15162 session_deps_.socket_factory->AddSocketDataProvider(&data);
15163
15164 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615165 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215166 // mocked. This way the request relies on the alternate Job.
15167 StaticSocketDataProvider data_refused;
15168 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15169 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15170
zhongyi3d4a55e72016-04-22 20:36:4615171 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015173 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215174 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115175 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215176 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115177 http_server_properties->SetHttp2AlternativeService(
15178 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215179
bnc5452e2a2015-05-08 16:27:4215180 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615181 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215182 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515183 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015184 request.traffic_annotation =
15185 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215186 TestCompletionCallback callback;
15187
15188 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215189 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015190 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215191 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215192}
15193
bnc40448a532015-05-11 19:13:1415194// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615195// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415196// succeeds, the request should succeed, even if the latter fails because
15197// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115198TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515199 url::SchemeHostPort server("https", "www.example.org", 443);
15200 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415201
15202 // Negotiate HTTP/1.1 with alternative.
15203 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615204 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415205 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15206
15207 // No data should be read from the alternative, because HTTP/1.1 is
15208 // negotiated.
15209 StaticSocketDataProvider data;
15210 session_deps_.socket_factory->AddSocketDataProvider(&data);
15211
zhongyi3d4a55e72016-04-22 20:36:4615212 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415213 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615214 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415215 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15216
15217 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515218 MockWrite("GET / HTTP/1.1\r\n"
15219 "Host: www.example.org\r\n"
15220 "Connection: keep-alive\r\n\r\n"),
15221 MockWrite("GET /second HTTP/1.1\r\n"
15222 "Host: www.example.org\r\n"
15223 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415224 };
15225
15226 MockRead http_reads[] = {
15227 MockRead("HTTP/1.1 200 OK\r\n"),
15228 MockRead("Content-Type: text/html\r\n"),
15229 MockRead("Content-Length: 6\r\n\r\n"),
15230 MockRead("foobar"),
15231 MockRead("HTTP/1.1 200 OK\r\n"),
15232 MockRead("Content-Type: text/html\r\n"),
15233 MockRead("Content-Length: 7\r\n\r\n"),
15234 MockRead("another"),
15235 };
15236 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15237 http_writes, arraysize(http_writes));
15238 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15239
zhongyi3d4a55e72016-04-22 20:36:4615240 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015242 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415243 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115244 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215245 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115246 http_server_properties->SetHttp2AlternativeService(
15247 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415248
15249 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15250 HttpRequestInfo request1;
15251 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515252 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415253 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015254 request1.traffic_annotation =
15255 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415256 TestCompletionCallback callback1;
15257
tfarina42834112016-09-22 13:38:2015258 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415259 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115260 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415261
15262 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215263 ASSERT_TRUE(response1);
15264 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415265 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15266
15267 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115268 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415269 EXPECT_EQ("foobar", response_data1);
15270
15271 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15272 // for alternative service.
15273 EXPECT_TRUE(
15274 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15275
zhongyi3d4a55e72016-04-22 20:36:4615276 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415277 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615278 // to server.
bnc40448a532015-05-11 19:13:1415279 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15280 HttpRequestInfo request2;
15281 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515282 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415283 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015284 request2.traffic_annotation =
15285 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415286 TestCompletionCallback callback2;
15287
tfarina42834112016-09-22 13:38:2015288 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415289 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115290 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415291
15292 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215293 ASSERT_TRUE(response2);
15294 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415295 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15296
15297 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115298 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415299 EXPECT_EQ("another", response_data2);
15300}
15301
bnc5452e2a2015-05-08 16:27:4215302// Alternative service requires HTTP/2 (or SPDY), but there is already a
15303// HTTP/1.1 socket open to the alternative server. That socket should not be
15304// used.
bncd16676a2016-07-20 16:23:0115305TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615306 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215307 HostPortPair alternative("alternative.example.org", 443);
15308 std::string origin_url = "https://origin.example.org:443";
15309 std::string alternative_url = "https://alternative.example.org:443";
15310
15311 // Negotiate HTTP/1.1 with alternative.example.org.
15312 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615313 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215314 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15315
15316 // HTTP/1.1 data for |request1| and |request2|.
15317 MockWrite http_writes[] = {
15318 MockWrite(
15319 "GET / HTTP/1.1\r\n"
15320 "Host: alternative.example.org\r\n"
15321 "Connection: keep-alive\r\n\r\n"),
15322 MockWrite(
15323 "GET / HTTP/1.1\r\n"
15324 "Host: alternative.example.org\r\n"
15325 "Connection: keep-alive\r\n\r\n"),
15326 };
15327
15328 MockRead http_reads[] = {
15329 MockRead(
15330 "HTTP/1.1 200 OK\r\n"
15331 "Content-Type: text/html; charset=iso-8859-1\r\n"
15332 "Content-Length: 40\r\n\r\n"
15333 "first HTTP/1.1 response from alternative"),
15334 MockRead(
15335 "HTTP/1.1 200 OK\r\n"
15336 "Content-Type: text/html; charset=iso-8859-1\r\n"
15337 "Content-Length: 41\r\n\r\n"
15338 "second HTTP/1.1 response from alternative"),
15339 };
15340 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15341 http_writes, arraysize(http_writes));
15342 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15343
15344 // This test documents that an alternate Job should not pool to an already
15345 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615346 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215347 StaticSocketDataProvider data_refused;
15348 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15349 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15350
zhongyi3d4a55e72016-04-22 20:36:4615351 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015353 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215354 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115355 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215356 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115357 http_server_properties->SetHttp2AlternativeService(
15358 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215359
15360 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215361 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615362 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215363 request1.method = "GET";
15364 request1.url = GURL(alternative_url);
15365 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015366 request1.traffic_annotation =
15367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215368 TestCompletionCallback callback1;
15369
tfarina42834112016-09-22 13:38:2015370 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115371 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615372 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215373 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215374 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215375 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215376 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215377 EXPECT_FALSE(response1->was_fetched_via_spdy);
15378 std::string response_data1;
bnc691fda62016-08-12 00:43:1615379 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215380 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15381
15382 // Request for origin.example.org, which has an alternative service. This
15383 // will start two Jobs: the alternative looks for connections to pool to,
15384 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615385 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215386 // this request fails.
bnc5452e2a2015-05-08 16:27:4215387 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615388 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215389 request2.method = "GET";
15390 request2.url = GURL(origin_url);
15391 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015392 request2.traffic_annotation =
15393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215394 TestCompletionCallback callback2;
15395
tfarina42834112016-09-22 13:38:2015396 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115397 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215398
15399 // Another transaction to alternative. This is to test that the HTTP/1.1
15400 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215401 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615402 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215403 request3.method = "GET";
15404 request3.url = GURL(alternative_url);
15405 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015406 request3.traffic_annotation =
15407 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215408 TestCompletionCallback callback3;
15409
tfarina42834112016-09-22 13:38:2015410 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115411 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615412 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215413 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215414 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215415 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215416 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215417 EXPECT_FALSE(response3->was_fetched_via_spdy);
15418 std::string response_data3;
bnc691fda62016-08-12 00:43:1615419 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215420 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15421}
15422
bncd16676a2016-07-20 16:23:0115423TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315424 const std::string https_url = "https://www.example.org:8080/";
15425 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415426
rdsmithebb50aa2015-11-12 03:44:3815427 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115428 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815429
[email protected]8450d722012-07-02 19:14:0415430 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315431 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115432 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415433 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115434 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915435 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115436 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215437 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915438
15439 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915440 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715441 req2_block[kHttp2MethodHeader] = "GET";
15442 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15443 req2_block[kHttp2SchemeHeader] = "http";
15444 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115445 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515446 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415447
15448 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115449 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15450 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415451 };
15452
bncdf80d44fd2016-07-15 20:27:4115453 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515454 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115455 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515456 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115457 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15458 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815459 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115460 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815461 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515462 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115463 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315464 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115465 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315466 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115467 CreateMockRead(wrapped_resp1, 4),
15468 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315469 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115470 CreateMockRead(resp2, 8),
15471 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315472 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15473 };
[email protected]8450d722012-07-02 19:14:0415474
mmenke666a6fea2015-12-19 04:16:3315475 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15476 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415477 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715478 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415479
Lily Houghton8c2f97d2018-01-22 05:06:5915480 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915481 ProxyResolutionService::CreateFixedFromPacResult(
15482 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115483 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715484 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415485 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615486 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415488 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615489 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15491 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415492
danakj1fd259a02016-04-16 03:17:0915493 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415494
15495 // Start the first transaction to set up the SpdySession
15496 HttpRequestInfo request1;
15497 request1.method = "GET";
15498 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415499 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015500 request1.traffic_annotation =
15501 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015502 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415503 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015504 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415505
mmenke666a6fea2015-12-19 04:16:3315506 // This pause is a hack to avoid running into https://crbug.com/497228.
15507 data1.RunUntilPaused();
15508 base::RunLoop().RunUntilIdle();
15509 data1.Resume();
robpercival214763f2016-07-01 23:27:0115510 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415511 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15512
[email protected]f6c63db52013-02-02 00:35:2215513 LoadTimingInfo load_timing_info1;
15514 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15515 TestLoadTimingNotReusedWithPac(load_timing_info1,
15516 CONNECT_TIMING_HAS_SSL_TIMES);
15517
mmenke666a6fea2015-12-19 04:16:3315518 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415519 HttpRequestInfo request2;
15520 request2.method = "GET";
15521 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415522 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015523 request2.traffic_annotation =
15524 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015525 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415526 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015527 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415528
mmenke666a6fea2015-12-19 04:16:3315529 // This pause is a hack to avoid running into https://crbug.com/497228.
15530 data1.RunUntilPaused();
15531 base::RunLoop().RunUntilIdle();
15532 data1.Resume();
robpercival214763f2016-07-01 23:27:0115533 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315534
[email protected]8450d722012-07-02 19:14:0415535 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215536
15537 LoadTimingInfo load_timing_info2;
15538 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15539 // The established SPDY sessions is considered reused by the HTTP request.
15540 TestLoadTimingReusedWithPac(load_timing_info2);
15541 // HTTP requests over a SPDY session should have a different connection
15542 // socket_log_id than requests over a tunnel.
15543 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415544}
15545
[email protected]2d88e7d2012-07-19 17:55:1715546// Test that in the case where we have a SPDY session to a SPDY proxy
15547// that we do not pool other origins that resolve to the same IP when
15548// the certificate does not match the new origin.
15549// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115550TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315551 const std::string url1 = "http://www.example.org/";
15552 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715553 const std::string ip_addr = "1.2.3.4";
15554
rdsmithebb50aa2015-11-12 03:44:3815555 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115556 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815557
[email protected]2d88e7d2012-07-19 17:55:1715558 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615559 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315560 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115561 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515562 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715563
15564 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115565 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715566 };
15567
bnc42331402016-07-25 13:36:1515568 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115569 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715570 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115571 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15572 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715573 };
15574
mmenke666a6fea2015-12-19 04:16:3315575 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15576 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215577 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915578 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715579 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15580 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315581 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715582
15583 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115584 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915585 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715586
15587 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115588 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715589 };
15590
bnc42331402016-07-25 13:36:1515591 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115592 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15593 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315594 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715595
mmenke666a6fea2015-12-19 04:16:3315596 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15597 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715598 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315599 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715600
15601 // Set up a proxy config that sends HTTP requests to a proxy, and
15602 // all others direct.
15603 ProxyConfig proxy_config;
15604 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915605 session_deps_.proxy_resolution_service =
15606 std::make_unique<ProxyResolutionService>(
15607 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15608 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15609 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715610
bncce36dca22015-04-21 22:11:2315611 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615612 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715613 // Load a valid cert. Note, that this does not need to
15614 // be valid for proxy because the MockSSLClientSocket does
15615 // not actually verify it. But SpdySession will use this
15616 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915617 ssl1.ssl_info.cert =
15618 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15619 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15621 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715622
15623 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615624 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15626 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715627
Jeremy Roman0579ed62017-08-29 15:56:1915628 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315629 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715630 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715631
danakj1fd259a02016-04-16 03:17:0915632 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715633
15634 // Start the first transaction to set up the SpdySession
15635 HttpRequestInfo request1;
15636 request1.method = "GET";
15637 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715638 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015639 request1.traffic_annotation =
15640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015641 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715642 TestCompletionCallback callback1;
15643 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015644 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315645 // This pause is a hack to avoid running into https://crbug.com/497228.
15646 data1.RunUntilPaused();
15647 base::RunLoop().RunUntilIdle();
15648 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715649
robpercival214763f2016-07-01 23:27:0115650 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715651 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15652
15653 // Now, start the HTTP request
15654 HttpRequestInfo request2;
15655 request2.method = "GET";
15656 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715657 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015658 request2.traffic_annotation =
15659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015660 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715661 TestCompletionCallback callback2;
15662 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015663 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515664 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715665
15666 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115667 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715668 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15669}
15670
[email protected]85f97342013-04-17 06:12:2415671// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15672// error) in SPDY session, removes the socket from pool and closes the SPDY
15673// session. Verify that new url's from the same HttpNetworkSession (and a new
15674// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115675TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315676 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415677
15678 MockRead reads1[] = {
15679 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15680 };
15681
mmenke11eb5152015-06-09 14:50:5015682 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415683
bncdf80d44fd2016-07-15 20:27:4115684 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915685 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415686 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115687 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415688 };
15689
bnc42331402016-07-25 13:36:1515690 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115691 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415692 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115693 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15694 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415695 };
15696
mmenke11eb5152015-06-09 14:50:5015697 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15698 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415699
[email protected]85f97342013-04-17 06:12:2415700 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615701 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15703 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415704
15705 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615706 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015707 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15708 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415709
danakj1fd259a02016-04-16 03:17:0915710 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015711 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415712
15713 // Start the first transaction to set up the SpdySession and verify that
15714 // connection was closed.
15715 HttpRequestInfo request1;
15716 request1.method = "GET";
15717 request1.url = GURL(https_url);
15718 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015719 request1.traffic_annotation =
15720 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015721 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415722 TestCompletionCallback callback1;
15723 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015724 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115725 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415726
15727 // Now, start the second request and make sure it succeeds.
15728 HttpRequestInfo request2;
15729 request2.method = "GET";
15730 request2.url = GURL(https_url);
15731 request2.load_flags = 0;
Ramin Halavatib5e433e2018-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]85f97342013-04-17 06:12:2415735 TestCompletionCallback callback2;
15736 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015737 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415738
robpercival214763f2016-07-01 23:27:0115739 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415740 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15741}
15742
bncd16676a2016-07-20 16:23:0115743TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315744 ClientSocketPoolManager::set_max_sockets_per_group(
15745 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15746 ClientSocketPoolManager::set_max_sockets_per_pool(
15747 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15748
15749 // Use two different hosts with different IPs so they don't get pooled.
15750 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15751 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315753
15754 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615755 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315756 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615757 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315758 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15760
bncdf80d44fd2016-07-15 20:27:4115761 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915762 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315763 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115764 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315765 };
bnc42331402016-07-25 13:36:1515766 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115767 SpdySerializedFrame host1_resp_body(
15768 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315769 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115770 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915771 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315772 };
15773
rdsmithebb50aa2015-11-12 03:44:3815774 // Use a separate test instance for the separate SpdySession that will be
15775 // created.
bncd16676a2016-07-20 16:23:0115776 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915777 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815778 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15779 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315780 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15781
bncdf80d44fd2016-07-15 20:27:4115782 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915783 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315784 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115785 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315786 };
bnc42331402016-07-25 13:36:1515787 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115788 SpdySerializedFrame host2_resp_body(
15789 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315790 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115791 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915792 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315793 };
15794
Jeremy Roman0579ed62017-08-29 15:56:1915795 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815796 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15797 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315798 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15799
15800 MockWrite http_write[] = {
15801 MockWrite("GET / HTTP/1.1\r\n"
15802 "Host: www.a.com\r\n"
15803 "Connection: keep-alive\r\n\r\n"),
15804 };
15805
15806 MockRead http_read[] = {
15807 MockRead("HTTP/1.1 200 OK\r\n"),
15808 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15809 MockRead("Content-Length: 6\r\n\r\n"),
15810 MockRead("hello!"),
15811 };
15812 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15813 http_write, arraysize(http_write));
15814 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15815
15816 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415817 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15818 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315819 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615820 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315821
15822 TestCompletionCallback callback;
15823 HttpRequestInfo request1;
15824 request1.method = "GET";
15825 request1.url = GURL("https://www.a.com/");
15826 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015827 request1.traffic_annotation =
15828 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815829 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915830 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315831
tfarina42834112016-09-22 13:38:2015832 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15834 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315835
15836 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215837 ASSERT_TRUE(response);
15838 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215839 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315840 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215841 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315842
15843 std::string response_data;
robpercival214763f2016-07-01 23:27:0115844 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315845 EXPECT_EQ("hello!", response_data);
15846 trans.reset();
15847 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615848 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315849
15850 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415851 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15852 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315853 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615854 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315855 HttpRequestInfo request2;
15856 request2.method = "GET";
15857 request2.url = GURL("https://www.b.com/");
15858 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015859 request2.traffic_annotation =
15860 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815861 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915862 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315863
tfarina42834112016-09-22 13:38:2015864 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15866 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315867
15868 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215869 ASSERT_TRUE(response);
15870 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215871 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315872 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215873 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115874 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315875 EXPECT_EQ("hello!", response_data);
15876 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615877 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315878 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615879 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315880
15881 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415882 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15883 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315884 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615885 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315886 HttpRequestInfo request3;
15887 request3.method = "GET";
15888 request3.url = GURL("http://www.a.com/");
15889 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015890 request3.traffic_annotation =
15891 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815892 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915893 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315894
tfarina42834112016-09-22 13:38:2015895 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15897 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315898
15899 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215900 ASSERT_TRUE(response);
15901 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315902 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15903 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215904 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115905 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315906 EXPECT_EQ("hello!", response_data);
15907 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615908 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315909 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615910 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315911}
15912
bncd16676a2016-07-20 16:23:0115913TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415914 HttpRequestInfo request;
15915 request.method = "GET";
bncce36dca22015-04-21 22:11:2315916 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015917 request.traffic_annotation =
15918 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415919
danakj1fd259a02016-04-16 03:17:0915920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615921 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415922
ttuttled9dbc652015-09-29 20:00:5915923 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415924 StaticSocketDataProvider data;
15925 data.set_connect_data(mock_connect);
15926 session_deps_.socket_factory->AddSocketDataProvider(&data);
15927
15928 TestCompletionCallback callback;
15929
tfarina42834112016-09-22 13:38:2015930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415932
15933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115934 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415935
[email protected]79e1fd62013-06-20 06:50:0415936 // We don't care whether this succeeds or fails, but it shouldn't crash.
15937 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615938 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715939
15940 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615941 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715942 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115943 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915944
15945 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615946 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915947 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415948}
15949
bncd16676a2016-07-20 16:23:0115950TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415951 HttpRequestInfo request;
15952 request.method = "GET";
bncce36dca22015-04-21 22:11:2315953 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015954 request.traffic_annotation =
15955 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415956
danakj1fd259a02016-04-16 03:17:0915957 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615958 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415959
ttuttled9dbc652015-09-29 20:00:5915960 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415961 StaticSocketDataProvider data;
15962 data.set_connect_data(mock_connect);
15963 session_deps_.socket_factory->AddSocketDataProvider(&data);
15964
15965 TestCompletionCallback callback;
15966
tfarina42834112016-09-22 13:38:2015967 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415969
15970 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115971 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415972
[email protected]79e1fd62013-06-20 06:50:0415973 // We don't care whether this succeeds or fails, but it shouldn't crash.
15974 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615975 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715976
15977 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615978 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715979 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115980 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915981
15982 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615983 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915984 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415985}
15986
bncd16676a2016-07-20 16:23:0115987TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415988 HttpRequestInfo request;
15989 request.method = "GET";
bncce36dca22015-04-21 22:11:2315990 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015991 request.traffic_annotation =
15992 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415993
danakj1fd259a02016-04-16 03:17:0915994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615995 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415996
15997 MockWrite data_writes[] = {
15998 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15999 };
16000 MockRead data_reads[] = {
16001 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16002 };
16003
16004 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16005 data_writes, arraysize(data_writes));
16006 session_deps_.socket_factory->AddSocketDataProvider(&data);
16007
16008 TestCompletionCallback callback;
16009
tfarina42834112016-09-22 13:38:2016010 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116011 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416012
16013 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116014 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416015
[email protected]79e1fd62013-06-20 06:50:0416016 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616017 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416018 EXPECT_TRUE(request_headers.HasHeader("Host"));
16019}
16020
bncd16676a2016-07-20 16:23:0116021TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416022 HttpRequestInfo request;
16023 request.method = "GET";
bncce36dca22015-04-21 22:11:2316024 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016025 request.traffic_annotation =
16026 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416027
danakj1fd259a02016-04-16 03:17:0916028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416030
16031 MockWrite data_writes[] = {
16032 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16033 };
16034 MockRead data_reads[] = {
16035 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16036 };
16037
16038 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16039 data_writes, arraysize(data_writes));
16040 session_deps_.socket_factory->AddSocketDataProvider(&data);
16041
16042 TestCompletionCallback callback;
16043
tfarina42834112016-09-22 13:38:2016044 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416046
16047 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116048 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416049
[email protected]79e1fd62013-06-20 06:50:0416050 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616051 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416052 EXPECT_TRUE(request_headers.HasHeader("Host"));
16053}
16054
bncd16676a2016-07-20 16:23:0116055TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416056 HttpRequestInfo request;
16057 request.method = "GET";
bncce36dca22015-04-21 22:11:2316058 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016059 request.traffic_annotation =
16060 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416061
danakj1fd259a02016-04-16 03:17:0916062 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616063 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416064
16065 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316066 MockWrite(
16067 "GET / HTTP/1.1\r\n"
16068 "Host: www.example.org\r\n"
16069 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416070 };
16071 MockRead data_reads[] = {
16072 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16073 };
16074
16075 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16076 data_writes, arraysize(data_writes));
16077 session_deps_.socket_factory->AddSocketDataProvider(&data);
16078
16079 TestCompletionCallback callback;
16080
tfarina42834112016-09-22 13:38:2016081 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416083
16084 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116085 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416086
[email protected]79e1fd62013-06-20 06:50:0416087 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616088 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416089 EXPECT_TRUE(request_headers.HasHeader("Host"));
16090}
16091
bncd16676a2016-07-20 16:23:0116092TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416093 HttpRequestInfo request;
16094 request.method = "GET";
bncce36dca22015-04-21 22:11:2316095 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016096 request.traffic_annotation =
16097 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416098
danakj1fd259a02016-04-16 03:17:0916099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416101
16102 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316103 MockWrite(
16104 "GET / HTTP/1.1\r\n"
16105 "Host: www.example.org\r\n"
16106 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416107 };
16108 MockRead data_reads[] = {
16109 MockRead(ASYNC, ERR_CONNECTION_RESET),
16110 };
16111
16112 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16113 data_writes, arraysize(data_writes));
16114 session_deps_.socket_factory->AddSocketDataProvider(&data);
16115
16116 TestCompletionCallback callback;
16117
tfarina42834112016-09-22 13:38:2016118 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116119 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416120
16121 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116122 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416123
[email protected]79e1fd62013-06-20 06:50:0416124 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616125 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416126 EXPECT_TRUE(request_headers.HasHeader("Host"));
16127}
16128
bncd16676a2016-07-20 16:23:0116129TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416130 HttpRequestInfo request;
16131 request.method = "GET";
bncce36dca22015-04-21 22:11:2316132 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416133 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016134 request.traffic_annotation =
16135 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416136
danakj1fd259a02016-04-16 03:17:0916137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616138 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416139
16140 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316141 MockWrite(
16142 "GET / HTTP/1.1\r\n"
16143 "Host: www.example.org\r\n"
16144 "Connection: keep-alive\r\n"
16145 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416146 };
16147 MockRead data_reads[] = {
16148 MockRead("HTTP/1.1 200 OK\r\n"
16149 "Content-Length: 5\r\n\r\n"
16150 "hello"),
16151 MockRead(ASYNC, ERR_UNEXPECTED),
16152 };
16153
16154 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16155 data_writes, arraysize(data_writes));
16156 session_deps_.socket_factory->AddSocketDataProvider(&data);
16157
16158 TestCompletionCallback callback;
16159
tfarina42834112016-09-22 13:38:2016160 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416162
16163 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116164 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416165
16166 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616167 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416168 std::string foo;
16169 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16170 EXPECT_EQ("bar", foo);
16171}
16172
[email protected]bf828982013-08-14 18:01:4716173namespace {
16174
yhiranoa7e05bb2014-11-06 05:40:3916175// Fake HttpStream that simply records calls to SetPriority().
16176class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0316177 public base::SupportsWeakPtr<FakeStream> {
16178 public:
16179 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2716180 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0316181
16182 RequestPriority priority() const { return priority_; }
16183
dchengb03027d2014-10-21 12:00:2016184 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716185 bool can_send_early,
dchengb03027d2014-10-21 12:00:2016186 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016187 const NetLogWithSource& net_log,
Bence Békya25e3f72018-02-13 21:13:3916188 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316189 return ERR_IO_PENDING;
16190 }
16191
dchengb03027d2014-10-21 12:00:2016192 int SendRequest(const HttpRequestHeaders& request_headers,
16193 HttpResponseInfo* response,
Bence Békya25e3f72018-02-13 21:13:3916194 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316195 ADD_FAILURE();
16196 return ERR_UNEXPECTED;
16197 }
16198
Bence Békya25e3f72018-02-13 21:13:3916199 int ReadResponseHeaders(CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316200 ADD_FAILURE();
16201 return ERR_UNEXPECTED;
16202 }
16203
dchengb03027d2014-10-21 12:00:2016204 int ReadResponseBody(IOBuffer* buf,
16205 int buf_len,
Bence Békya25e3f72018-02-13 21:13:3916206 CompletionOnceCallback callback) override {
[email protected]e86839fd2013-08-14 18:29:0316207 ADD_FAILURE();
16208 return ERR_UNEXPECTED;
16209 }
16210
dchengb03027d2014-10-21 12:00:2016211 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0316212
dchengb03027d2014-10-21 12:00:2016213 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0316214 ADD_FAILURE();
16215 return false;
16216 }
16217
dchengb03027d2014-10-21 12:00:2016218 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0316219 ADD_FAILURE();
16220 return false;
16221 }
16222
dchengb03027d2014-10-21 12:00:2016223 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316224
mmenkebd84c392015-09-02 14:12:3416225 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0316226
sclittle4de1bab92015-09-22 21:28:2416227 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5916228 ADD_FAILURE();
16229 return 0;
16230 }
16231
sclittlebe1ccf62015-09-02 19:40:3616232 int64_t GetTotalSentBytes() const override {
16233 ADD_FAILURE();
16234 return 0;
16235 }
16236
dchengb03027d2014-10-21 12:00:2016237 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0316238 ADD_FAILURE();
16239 return false;
16240 }
16241
rchcd379012017-04-12 21:53:3216242 bool GetAlternativeService(
16243 AlternativeService* alternative_service) const override {
16244 ADD_FAILURE();
16245 return false;
16246 }
16247
dchengb03027d2014-10-21 12:00:2016248 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
16249
16250 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0316251 ADD_FAILURE();
16252 }
16253
ttuttled9dbc652015-09-29 20:00:5916254 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16255
nharper78e6d2b2016-09-21 05:42:3516256 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16257 TokenBindingType tb_type,
16258 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416259 ADD_FAILURE();
16260 return ERR_NOT_IMPLEMENTED;
16261 }
16262
dchengb03027d2014-10-21 12:00:2016263 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316264
zhongyica364fbb2015-12-12 03:39:1216265 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16266
dchengb03027d2014-10-21 12:00:2016267 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0316268
yhiranoa7e05bb2014-11-06 05:40:3916269 HttpStream* RenewStreamForAuth() override { return NULL; }
16270
Andrey Kosyakov83a6eee2017-08-14 19:20:0416271 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
16272
[email protected]e86839fd2013-08-14 18:29:0316273 private:
16274 RequestPriority priority_;
16275
16276 DISALLOW_COPY_AND_ASSIGN(FakeStream);
16277};
16278
16279// Fake HttpStreamRequest that simply records calls to SetPriority()
16280// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4716281class FakeStreamRequest : public HttpStreamRequest,
16282 public base::SupportsWeakPtr<FakeStreamRequest> {
16283 public:
[email protected]e86839fd2013-08-14 18:29:0316284 FakeStreamRequest(RequestPriority priority,
16285 HttpStreamRequest::Delegate* delegate)
16286 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4416287 delegate_(delegate),
16288 websocket_stream_create_helper_(NULL) {}
16289
16290 FakeStreamRequest(RequestPriority priority,
16291 HttpStreamRequest::Delegate* delegate,
16292 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
16293 : priority_(priority),
16294 delegate_(delegate),
16295 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0316296
Chris Watkins7a41d3552017-12-01 02:13:2716297 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4716298
16299 RequestPriority priority() const { return priority_; }
16300
[email protected]831e4a32013-11-14 02:14:4416301 const WebSocketHandshakeStreamBase::CreateHelper*
16302 websocket_stream_create_helper() const {
16303 return websocket_stream_create_helper_;
16304 }
16305
[email protected]e86839fd2013-08-14 18:29:0316306 // Create a new FakeStream and pass it to the request's
16307 // delegate. Returns a weak pointer to the FakeStream.
16308 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1916309 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0316310 // Do this before calling OnStreamReady() as OnStreamReady() may
16311 // immediately delete |fake_stream|.
16312 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0016313 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0316314 return weak_stream;
16315 }
16316
asanka681f02d2017-02-22 17:06:3916317 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4716318 ADD_FAILURE();
16319 return ERR_UNEXPECTED;
16320 }
16321
dchengb03027d2014-10-21 12:00:2016322 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4716323 ADD_FAILURE();
16324 return LoadState();
16325 }
16326
dchengb03027d2014-10-21 12:00:2016327 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4716328
bnc94c92842016-09-21 15:22:5216329 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716330
bnc6227b26e2016-08-12 02:00:4316331 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4716332
dchengb03027d2014-10-21 12:00:2016333 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716334
ttuttle1f2d7e92015-04-28 16:17:4716335 const ConnectionAttempts& connection_attempts() const override {
16336 static ConnectionAttempts no_attempts;
16337 return no_attempts;
16338 }
16339
[email protected]bf828982013-08-14 18:01:4716340 private:
16341 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0316342 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4416343 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4716344
16345 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
16346};
16347
16348// Fake HttpStreamFactory that vends FakeStreamRequests.
16349class FakeStreamFactory : public HttpStreamFactory {
16350 public:
Chris Watkins7a41d3552017-12-01 02:13:2716351 FakeStreamFactory() = default;
16352 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4716353
16354 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
16355 // RequestStream() (which may be NULL if it was destroyed already).
16356 base::WeakPtr<FakeStreamRequest> last_stream_request() {
16357 return last_stream_request_;
16358 }
16359
xunjieli96f2a402017-06-05 17:24:2716360 std::unique_ptr<HttpStreamRequest> RequestStream(
16361 const HttpRequestInfo& info,
16362 RequestPriority priority,
16363 const SSLConfig& server_ssl_config,
16364 const SSLConfig& proxy_ssl_config,
16365 HttpStreamRequest::Delegate* delegate,
16366 bool enable_ip_based_pooling,
16367 bool enable_alternative_services,
16368 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1916369 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4716370 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716371 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716372 }
16373
xunjieli96f2a402017-06-05 17:24:2716374 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0816375 const HttpRequestInfo& info,
16376 RequestPriority priority,
16377 const SSLConfig& server_ssl_config,
16378 const SSLConfig& proxy_ssl_config,
16379 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2916380 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616381 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016382 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0816383 NOTREACHED();
16384 return nullptr;
16385 }
16386
xunjieli96f2a402017-06-05 17:24:2716387 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4716388 const HttpRequestInfo& info,
16389 RequestPriority priority,
16390 const SSLConfig& server_ssl_config,
16391 const SSLConfig& proxy_ssl_config,
16392 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4616393 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2916394 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616395 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016396 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2716397 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1916398 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4416399 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716400 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716401 }
16402
dchengb03027d2014-10-21 12:00:2016403 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5916404 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4716405 ADD_FAILURE();
16406 }
16407
dchengb03027d2014-10-21 12:00:2016408 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4716409 ADD_FAILURE();
16410 return NULL;
16411 }
16412
xunjielif5267de2017-01-20 21:18:5716413 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
16414 const std::string& parent_absolute_name) const override {
16415 ADD_FAILURE();
16416 }
16417
[email protected]bf828982013-08-14 18:01:4716418 private:
16419 base::WeakPtr<FakeStreamRequest> last_stream_request_;
16420
16421 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16422};
16423
[email protected]bf828982013-08-14 18:01:4716424} // namespace
16425
16426// Make sure that HttpNetworkTransaction passes on its priority to its
16427// stream request on start.
bncd16676a2016-07-20 16:23:0116428TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216430 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716431 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916432 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716433
krasinc06a72a2016-12-21 03:42:4616434 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116435 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716436
Ramin Halavatib5e433e2018-02-07 07:41:1016437 request.traffic_annotation =
16438 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16439
wezca1070932016-05-26 20:30:5216440 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716441
[email protected]bf828982013-08-14 18:01:4716442 TestCompletionCallback callback;
16443 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016444 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716445
16446 base::WeakPtr<FakeStreamRequest> fake_request =
16447 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216448 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716449 EXPECT_EQ(LOW, fake_request->priority());
16450}
16451
16452// Make sure that HttpNetworkTransaction passes on its priority
16453// updates to its stream request.
bncd16676a2016-07-20 16:23:0116454TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216456 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716457 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916458 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716459
krasinc06a72a2016-12-21 03:42:4616460 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116461 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716462
Ramin Halavatib5e433e2018-02-07 07:41:1016463 request.traffic_annotation =
16464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16465
[email protected]bf828982013-08-14 18:01:4716466 TestCompletionCallback callback;
16467 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016468 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716469
16470 base::WeakPtr<FakeStreamRequest> fake_request =
16471 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216472 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716473 EXPECT_EQ(LOW, fake_request->priority());
16474
16475 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216476 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716477 EXPECT_EQ(LOWEST, fake_request->priority());
16478}
16479
[email protected]e86839fd2013-08-14 18:29:0316480// Make sure that HttpNetworkTransaction passes on its priority
16481// updates to its stream.
bncd16676a2016-07-20 16:23:0116482TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916483 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216484 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316485 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916486 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316487
krasinc06a72a2016-12-21 03:42:4616488 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116489 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316490
Ramin Halavatib5e433e2018-02-07 07:41:1016491 request.traffic_annotation =
16492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16493
[email protected]e86839fd2013-08-14 18:29:0316494 TestCompletionCallback callback;
16495 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016496 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316497
16498 base::WeakPtr<FakeStreamRequest> fake_request =
16499 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216500 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316501 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216502 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316503 EXPECT_EQ(LOW, fake_stream->priority());
16504
16505 trans.SetPriority(LOWEST);
16506 EXPECT_EQ(LOWEST, fake_stream->priority());
16507}
16508
[email protected]043b68c82013-08-22 23:41:5216509// Tests that when a used socket is returned to the SSL socket pool, it's closed
16510// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116511TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216512 ClientSocketPoolManager::set_max_sockets_per_group(
16513 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16514 ClientSocketPoolManager::set_max_sockets_per_pool(
16515 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16516
16517 // Set up SSL request.
16518
16519 HttpRequestInfo ssl_request;
16520 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316521 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016522 ssl_request.traffic_annotation =
16523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216524
16525 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316526 MockWrite(
16527 "GET / HTTP/1.1\r\n"
16528 "Host: www.example.org\r\n"
16529 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216530 };
16531 MockRead ssl_reads[] = {
16532 MockRead("HTTP/1.1 200 OK\r\n"),
16533 MockRead("Content-Length: 11\r\n\r\n"),
16534 MockRead("hello world"),
16535 MockRead(SYNCHRONOUS, OK),
16536 };
16537 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16538 ssl_writes, arraysize(ssl_writes));
16539 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16540
16541 SSLSocketDataProvider ssl(ASYNC, OK);
16542 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16543
16544 // Set up HTTP request.
16545
16546 HttpRequestInfo http_request;
16547 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316548 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016549 http_request.traffic_annotation =
16550 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216551
16552 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316553 MockWrite(
16554 "GET / HTTP/1.1\r\n"
16555 "Host: www.example.org\r\n"
16556 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216557 };
16558 MockRead http_reads[] = {
16559 MockRead("HTTP/1.1 200 OK\r\n"),
16560 MockRead("Content-Length: 7\r\n\r\n"),
16561 MockRead("falafel"),
16562 MockRead(SYNCHRONOUS, OK),
16563 };
16564 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16565 http_writes, arraysize(http_writes));
16566 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16567
danakj1fd259a02016-04-16 03:17:0916568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216569
16570 // Start the SSL request.
16571 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616572 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016573 ASSERT_EQ(ERR_IO_PENDING,
16574 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16575 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216576
16577 // Start the HTTP request. Pool should stall.
16578 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616579 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016580 ASSERT_EQ(ERR_IO_PENDING,
16581 http_trans.Start(&http_request, http_callback.callback(),
16582 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116583 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216584
16585 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116586 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216587 std::string response_data;
bnc691fda62016-08-12 00:43:1616588 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216589 EXPECT_EQ("hello world", response_data);
16590
16591 // The SSL socket should automatically be closed, so the HTTP request can
16592 // start.
dcheng48459ac22014-08-26 00:46:4116593 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16594 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216595
16596 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116597 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616598 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216599 EXPECT_EQ("falafel", response_data);
16600
dcheng48459ac22014-08-26 00:46:4116601 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216602}
16603
16604// Tests that when a SSL connection is established but there's no corresponding
16605// request that needs it, the new socket is closed if the transport socket pool
16606// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116607TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216608 ClientSocketPoolManager::set_max_sockets_per_group(
16609 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16610 ClientSocketPoolManager::set_max_sockets_per_pool(
16611 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16612
16613 // Set up an ssl request.
16614
16615 HttpRequestInfo ssl_request;
16616 ssl_request.method = "GET";
16617 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1016618 ssl_request.traffic_annotation =
16619 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216620
16621 // No data will be sent on the SSL socket.
16622 StaticSocketDataProvider ssl_data;
16623 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16624
16625 SSLSocketDataProvider ssl(ASYNC, OK);
16626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16627
16628 // Set up HTTP request.
16629
16630 HttpRequestInfo http_request;
16631 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316632 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016633 http_request.traffic_annotation =
16634 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216635
16636 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316637 MockWrite(
16638 "GET / HTTP/1.1\r\n"
16639 "Host: www.example.org\r\n"
16640 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216641 };
16642 MockRead http_reads[] = {
16643 MockRead("HTTP/1.1 200 OK\r\n"),
16644 MockRead("Content-Length: 7\r\n\r\n"),
16645 MockRead("falafel"),
16646 MockRead(SYNCHRONOUS, OK),
16647 };
16648 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16649 http_writes, arraysize(http_writes));
16650 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16651
danakj1fd259a02016-04-16 03:17:0916652 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216653
16654 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16655 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916656 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916657 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116658 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216659
16660 // Start the HTTP request. Pool should stall.
16661 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616662 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016663 ASSERT_EQ(ERR_IO_PENDING,
16664 http_trans.Start(&http_request, http_callback.callback(),
16665 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116666 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216667
16668 // The SSL connection will automatically be closed once the connection is
16669 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116670 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216671 std::string response_data;
bnc691fda62016-08-12 00:43:1616672 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216673 EXPECT_EQ("falafel", response_data);
16674
dcheng48459ac22014-08-26 00:46:4116675 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216676}
16677
bncd16676a2016-07-20 16:23:0116678TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916679 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216680 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916681 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216682 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416683
16684 HttpRequestInfo request;
16685 request.method = "POST";
16686 request.url = GURL("http://www.foo.com/");
16687 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016688 request.traffic_annotation =
16689 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416690
danakj1fd259a02016-04-16 03:17:0916691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616692 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416693 // Send headers successfully, but get an error while sending the body.
16694 MockWrite data_writes[] = {
16695 MockWrite("POST / HTTP/1.1\r\n"
16696 "Host: www.foo.com\r\n"
16697 "Connection: keep-alive\r\n"
16698 "Content-Length: 3\r\n\r\n"),
16699 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16700 };
16701
16702 MockRead data_reads[] = {
16703 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16704 MockRead("hello world"),
16705 MockRead(SYNCHRONOUS, OK),
16706 };
16707 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16708 arraysize(data_writes));
16709 session_deps_.socket_factory->AddSocketDataProvider(&data);
16710
16711 TestCompletionCallback callback;
16712
tfarina42834112016-09-22 13:38:2016713 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416715
16716 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116717 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416718
bnc691fda62016-08-12 00:43:1616719 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216720 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416721
wezca1070932016-05-26 20:30:5216722 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416723 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16724
16725 std::string response_data;
bnc691fda62016-08-12 00:43:1616726 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116727 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416728 EXPECT_EQ("hello world", response_data);
16729}
16730
16731// This test makes sure the retry logic doesn't trigger when reading an error
16732// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116733TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416734 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416736 MockWrite data_writes[] = {
16737 MockWrite("GET / HTTP/1.1\r\n"
16738 "Host: www.foo.com\r\n"
16739 "Connection: keep-alive\r\n\r\n"),
16740 MockWrite("POST / HTTP/1.1\r\n"
16741 "Host: www.foo.com\r\n"
16742 "Connection: keep-alive\r\n"
16743 "Content-Length: 3\r\n\r\n"),
16744 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16745 };
16746
16747 MockRead data_reads[] = {
16748 MockRead("HTTP/1.1 200 Peachy\r\n"
16749 "Content-Length: 14\r\n\r\n"),
16750 MockRead("first response"),
16751 MockRead("HTTP/1.1 400 Not OK\r\n"
16752 "Content-Length: 15\r\n\r\n"),
16753 MockRead("second response"),
16754 MockRead(SYNCHRONOUS, OK),
16755 };
16756 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16757 arraysize(data_writes));
16758 session_deps_.socket_factory->AddSocketDataProvider(&data);
16759
16760 TestCompletionCallback callback;
16761 HttpRequestInfo request1;
16762 request1.method = "GET";
16763 request1.url = GURL("http://www.foo.com/");
16764 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016765 request1.traffic_annotation =
16766 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416767
bnc87dcefc2017-05-25 12:47:5816768 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916769 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016770 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416772
16773 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116774 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416775
16776 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216777 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416778
wezca1070932016-05-26 20:30:5216779 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416780 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16781
16782 std::string response_data1;
16783 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116784 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416785 EXPECT_EQ("first response", response_data1);
16786 // Delete the transaction to release the socket back into the socket pool.
16787 trans1.reset();
16788
danakj1fd259a02016-04-16 03:17:0916789 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216790 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916791 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216792 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416793
16794 HttpRequestInfo request2;
16795 request2.method = "POST";
16796 request2.url = GURL("http://www.foo.com/");
16797 request2.upload_data_stream = &upload_data_stream;
16798 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016799 request2.traffic_annotation =
16800 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416801
bnc691fda62016-08-12 00:43:1616802 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016803 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416805
16806 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116807 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416808
bnc691fda62016-08-12 00:43:1616809 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216810 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416811
wezca1070932016-05-26 20:30:5216812 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416813 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16814
16815 std::string response_data2;
bnc691fda62016-08-12 00:43:1616816 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116817 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416818 EXPECT_EQ("second response", response_data2);
16819}
16820
bncd16676a2016-07-20 16:23:0116821TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416822 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916823 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216824 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916825 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216826 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416827
16828 HttpRequestInfo request;
16829 request.method = "POST";
16830 request.url = GURL("http://www.foo.com/");
16831 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016832 request.traffic_annotation =
16833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416834
danakj1fd259a02016-04-16 03:17:0916835 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616836 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416837 // Send headers successfully, but get an error while sending the body.
16838 MockWrite data_writes[] = {
16839 MockWrite("POST / HTTP/1.1\r\n"
16840 "Host: www.foo.com\r\n"
16841 "Connection: keep-alive\r\n"
16842 "Content-Length: 3\r\n\r\n"
16843 "fo"),
16844 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16845 };
16846
16847 MockRead data_reads[] = {
16848 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16849 MockRead("hello world"),
16850 MockRead(SYNCHRONOUS, OK),
16851 };
16852 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16853 arraysize(data_writes));
16854 session_deps_.socket_factory->AddSocketDataProvider(&data);
16855
16856 TestCompletionCallback callback;
16857
tfarina42834112016-09-22 13:38:2016858 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116859 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416860
16861 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116862 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416863
bnc691fda62016-08-12 00:43:1616864 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216865 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416866
wezca1070932016-05-26 20:30:5216867 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416868 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16869
16870 std::string response_data;
bnc691fda62016-08-12 00:43:1616871 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116872 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416873 EXPECT_EQ("hello world", response_data);
16874}
16875
16876// This tests the more common case than the previous test, where headers and
16877// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116878TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716879 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416880
16881 HttpRequestInfo request;
16882 request.method = "POST";
16883 request.url = GURL("http://www.foo.com/");
16884 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016885 request.traffic_annotation =
16886 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416887
danakj1fd259a02016-04-16 03:17:0916888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416890 // Send headers successfully, but get an error while sending the body.
16891 MockWrite data_writes[] = {
16892 MockWrite("POST / HTTP/1.1\r\n"
16893 "Host: www.foo.com\r\n"
16894 "Connection: keep-alive\r\n"
16895 "Transfer-Encoding: chunked\r\n\r\n"),
16896 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16897 };
16898
16899 MockRead data_reads[] = {
16900 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16901 MockRead("hello world"),
16902 MockRead(SYNCHRONOUS, OK),
16903 };
16904 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16905 arraysize(data_writes));
16906 session_deps_.socket_factory->AddSocketDataProvider(&data);
16907
16908 TestCompletionCallback callback;
16909
tfarina42834112016-09-22 13:38:2016910 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416912 // Make sure the headers are sent before adding a chunk. This ensures that
16913 // they can't be merged with the body in a single send. Not currently
16914 // necessary since a chunked body is never merged with headers, but this makes
16915 // the test more future proof.
16916 base::RunLoop().RunUntilIdle();
16917
mmenkecbc2b712014-10-09 20:29:0716918 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416919
16920 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116921 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416922
bnc691fda62016-08-12 00:43:1616923 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216924 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416925
wezca1070932016-05-26 20:30:5216926 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416927 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16928
16929 std::string response_data;
bnc691fda62016-08-12 00:43:1616930 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116931 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416932 EXPECT_EQ("hello world", response_data);
16933}
16934
bncd16676a2016-07-20 16:23:0116935TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916936 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216937 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916938 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216939 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416940
16941 HttpRequestInfo request;
16942 request.method = "POST";
16943 request.url = GURL("http://www.foo.com/");
16944 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016945 request.traffic_annotation =
16946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416947
danakj1fd259a02016-04-16 03:17:0916948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416950
16951 MockWrite data_writes[] = {
16952 MockWrite("POST / HTTP/1.1\r\n"
16953 "Host: www.foo.com\r\n"
16954 "Connection: keep-alive\r\n"
16955 "Content-Length: 3\r\n\r\n"),
16956 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16957 };
16958
16959 MockRead data_reads[] = {
16960 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16961 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16962 MockRead("hello world"),
16963 MockRead(SYNCHRONOUS, OK),
16964 };
16965 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16966 arraysize(data_writes));
16967 session_deps_.socket_factory->AddSocketDataProvider(&data);
16968
16969 TestCompletionCallback callback;
16970
tfarina42834112016-09-22 13:38:2016971 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416973
16974 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116975 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416976
bnc691fda62016-08-12 00:43:1616977 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216978 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416979
wezca1070932016-05-26 20:30:5216980 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416981 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16982
16983 std::string response_data;
bnc691fda62016-08-12 00:43:1616984 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116985 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416986 EXPECT_EQ("hello world", response_data);
16987}
16988
bncd16676a2016-07-20 16:23:0116989TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916990 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216991 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916992 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216993 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416994
16995 HttpRequestInfo request;
16996 request.method = "POST";
16997 request.url = GURL("http://www.foo.com/");
16998 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016999 request.traffic_annotation =
17000 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417001
danakj1fd259a02016-04-16 03:17:0917002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617003 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417004 // Send headers successfully, but get an error while sending the body.
17005 MockWrite data_writes[] = {
17006 MockWrite("POST / HTTP/1.1\r\n"
17007 "Host: www.foo.com\r\n"
17008 "Connection: keep-alive\r\n"
17009 "Content-Length: 3\r\n\r\n"),
17010 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17011 };
17012
17013 MockRead data_reads[] = {
17014 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17015 MockRead("hello world"),
17016 MockRead(SYNCHRONOUS, OK),
17017 };
17018 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17019 arraysize(data_writes));
17020 session_deps_.socket_factory->AddSocketDataProvider(&data);
17021
17022 TestCompletionCallback callback;
17023
tfarina42834112016-09-22 13:38:2017024 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117025 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417026
17027 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117028 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417029}
17030
bncd16676a2016-07-20 16:23:0117031TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417032 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917033 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217034 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917035 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217036 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417037
17038 HttpRequestInfo request;
17039 request.method = "POST";
17040 request.url = GURL("http://www.foo.com/");
17041 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017042 request.traffic_annotation =
17043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417044
danakj1fd259a02016-04-16 03:17:0917045 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417047 // Send headers successfully, but get an error while sending the body.
17048 MockWrite data_writes[] = {
17049 MockWrite("POST / HTTP/1.1\r\n"
17050 "Host: www.foo.com\r\n"
17051 "Connection: keep-alive\r\n"
17052 "Content-Length: 3\r\n\r\n"),
17053 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17054 };
17055
17056 MockRead data_reads[] = {
17057 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17058 MockRead("HTTP/1.0 302 Redirect\r\n"),
17059 MockRead("Location: http://somewhere-else.com/\r\n"),
17060 MockRead("Content-Length: 0\r\n\r\n"),
17061 MockRead(SYNCHRONOUS, OK),
17062 };
17063 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17064 arraysize(data_writes));
17065 session_deps_.socket_factory->AddSocketDataProvider(&data);
17066
17067 TestCompletionCallback callback;
17068
tfarina42834112016-09-22 13:38:2017069 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417071
17072 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117073 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417074}
17075
bncd16676a2016-07-20 16:23:0117076TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917077 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217078 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917079 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217080 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417081
17082 HttpRequestInfo request;
17083 request.method = "POST";
17084 request.url = GURL("http://www.foo.com/");
17085 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017086 request.traffic_annotation =
17087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417088
danakj1fd259a02016-04-16 03:17:0917089 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617090 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417091 // Send headers successfully, but get an error while sending the body.
17092 MockWrite data_writes[] = {
17093 MockWrite("POST / HTTP/1.1\r\n"
17094 "Host: www.foo.com\r\n"
17095 "Connection: keep-alive\r\n"
17096 "Content-Length: 3\r\n\r\n"),
17097 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17098 };
17099
17100 MockRead data_reads[] = {
17101 MockRead("HTTP 0.9 rocks!"),
17102 MockRead(SYNCHRONOUS, OK),
17103 };
17104 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17105 arraysize(data_writes));
17106 session_deps_.socket_factory->AddSocketDataProvider(&data);
17107
17108 TestCompletionCallback callback;
17109
tfarina42834112016-09-22 13:38:2017110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417112
17113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117114 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417115}
17116
bncd16676a2016-07-20 16:23:0117117TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917118 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217119 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917120 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217121 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417122
17123 HttpRequestInfo request;
17124 request.method = "POST";
17125 request.url = GURL("http://www.foo.com/");
17126 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017127 request.traffic_annotation =
17128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417129
danakj1fd259a02016-04-16 03:17:0917130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417132 // Send headers successfully, but get an error while sending the body.
17133 MockWrite data_writes[] = {
17134 MockWrite("POST / HTTP/1.1\r\n"
17135 "Host: www.foo.com\r\n"
17136 "Connection: keep-alive\r\n"
17137 "Content-Length: 3\r\n\r\n"),
17138 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17139 };
17140
17141 MockRead data_reads[] = {
17142 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17143 MockRead(SYNCHRONOUS, OK),
17144 };
17145 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17146 arraysize(data_writes));
17147 session_deps_.socket_factory->AddSocketDataProvider(&data);
17148
17149 TestCompletionCallback callback;
17150
tfarina42834112016-09-22 13:38:2017151 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417153
17154 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117155 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417156}
17157
Bence Békydca6bd92018-01-30 13:43:0617158#if BUILDFLAG(ENABLE_WEBSOCKETS)
17159
17160namespace {
17161
17162void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17163 headers->SetHeader("Connection", "Upgrade");
17164 headers->SetHeader("Upgrade", "websocket");
17165 headers->SetHeader("Origin", "http://www.example.org");
17166 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617167}
17168
17169} // namespace
17170
17171TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
17172 // The same logic needs to be tested for both ws: and wss: schemes, but this
17173 // test is already parameterised on NextProto, so it uses a loop to verify
17174 // that the different schemes work.
17175 std::string test_cases[] = {"ws://www.example.org/",
17176 "wss://www.example.org/"};
17177 for (size_t i = 0; i < arraysize(test_cases); ++i) {
17178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17179 HttpNetworkSessionPeer peer(session.get());
17180 FakeStreamFactory* fake_factory = new FakeStreamFactory();
17181 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
17182
17183 HttpRequestInfo request;
17184 request.method = "GET";
17185 request.url = GURL(test_cases[i]);
Ramin Halavatib5e433e2018-02-07 07:41:1017186 request.traffic_annotation =
17187 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617188
Bence Béky8d1c6052018-02-07 12:48:1517189 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17190
Bence Békydca6bd92018-01-30 13:43:0617191 HttpNetworkTransaction trans(LOW, session.get());
17192 trans.SetWebSocketHandshakeStreamCreateHelper(
17193 &websocket_stream_create_helper);
17194
17195 TestCompletionCallback callback;
17196 EXPECT_EQ(ERR_IO_PENDING,
17197 trans.Start(&request, callback.callback(), NetLogWithSource()));
17198
17199 base::WeakPtr<FakeStreamRequest> fake_request =
17200 fake_factory->last_stream_request();
17201 ASSERT_TRUE(fake_request);
17202 EXPECT_EQ(&websocket_stream_create_helper,
17203 fake_request->websocket_stream_create_helper());
17204 }
17205}
17206
Adam Rice425cf122015-01-19 06:18:2417207// Verify that proxy headers are not sent to the destination server when
17208// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117209TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417210 HttpRequestInfo request;
17211 request.method = "GET";
bncce36dca22015-04-21 22:11:2317212 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017213 request.traffic_annotation =
17214 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417215 AddWebSocketHeaders(&request.extra_headers);
17216
17217 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917218 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917219 ProxyResolutionService::CreateFixedFromPacResult(
17220 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417221
danakj1fd259a02016-04-16 03:17:0917222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417223
17224 // Since a proxy is configured, try to establish a tunnel.
17225 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717226 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17227 "Host: www.example.org:443\r\n"
17228 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417229
17230 // After calling trans->RestartWithAuth(), this is the request we should
17231 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717232 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17233 "Host: www.example.org:443\r\n"
17234 "Proxy-Connection: keep-alive\r\n"
17235 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417236
rsleevidb16bb02015-11-12 23:47:1717237 MockWrite("GET / HTTP/1.1\r\n"
17238 "Host: www.example.org\r\n"
17239 "Connection: Upgrade\r\n"
17240 "Upgrade: websocket\r\n"
17241 "Origin: http://www.example.org\r\n"
17242 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517243 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17244 "Sec-WebSocket-Extensions: permessage-deflate; "
17245 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417246
17247 // The proxy responds to the connect with a 407, using a persistent
17248 // connection.
17249 MockRead data_reads[] = {
17250 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517251 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17252 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17253 "Content-Length: 0\r\n"
17254 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417255
17256 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17257
Bence Béky8d1c6052018-02-07 12:48:1517258 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17259 "Upgrade: websocket\r\n"
17260 "Connection: Upgrade\r\n"
17261 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417262
17263 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17264 arraysize(data_writes));
17265 session_deps_.socket_factory->AddSocketDataProvider(&data);
17266 SSLSocketDataProvider ssl(ASYNC, OK);
17267 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17268
Bence Béky8d1c6052018-02-07 12:48:1517269 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17270
bnc87dcefc2017-05-25 12:47:5817271 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917272 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417273 trans->SetWebSocketHandshakeStreamCreateHelper(
17274 &websocket_stream_create_helper);
17275
17276 {
17277 TestCompletionCallback callback;
17278
tfarina42834112016-09-22 13:38:2017279 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417281
17282 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117283 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417284 }
17285
17286 const HttpResponseInfo* response = trans->GetResponseInfo();
17287 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217288 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417289 EXPECT_EQ(407, response->headers->response_code());
17290
17291 {
17292 TestCompletionCallback callback;
17293
17294 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17295 callback.callback());
robpercival214763f2016-07-01 23:27:0117296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417297
17298 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117299 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417300 }
17301
17302 response = trans->GetResponseInfo();
17303 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217304 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417305
17306 EXPECT_EQ(101, response->headers->response_code());
17307
17308 trans.reset();
17309 session->CloseAllConnections();
17310}
17311
17312// Verify that proxy headers are not sent to the destination server when
17313// establishing a tunnel for an insecure WebSocket connection.
17314// This requires the authentication info to be injected into the auth cache
17315// due to crbug.com/395064
17316// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117317TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417318 HttpRequestInfo request;
17319 request.method = "GET";
bncce36dca22015-04-21 22:11:2317320 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017321 request.traffic_annotation =
17322 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417323 AddWebSocketHeaders(&request.extra_headers);
17324
17325 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917326 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917327 ProxyResolutionService::CreateFixedFromPacResult(
17328 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417329
danakj1fd259a02016-04-16 03:17:0917330 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417331
17332 MockWrite data_writes[] = {
17333 // Try to establish a tunnel for the WebSocket connection, with
17334 // credentials. Because WebSockets have a separate set of socket pools,
17335 // they cannot and will not use the same TCP/IP connection as the
17336 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517337 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17338 "Host: www.example.org:80\r\n"
17339 "Proxy-Connection: keep-alive\r\n"
17340 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417341
Bence Béky8d1c6052018-02-07 12:48:1517342 MockWrite("GET / HTTP/1.1\r\n"
17343 "Host: www.example.org\r\n"
17344 "Connection: Upgrade\r\n"
17345 "Upgrade: websocket\r\n"
17346 "Origin: http://www.example.org\r\n"
17347 "Sec-WebSocket-Version: 13\r\n"
17348 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17349 "Sec-WebSocket-Extensions: permessage-deflate; "
17350 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417351
17352 MockRead data_reads[] = {
17353 // HTTP CONNECT with credentials.
17354 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17355
17356 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517357 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17358 "Upgrade: websocket\r\n"
17359 "Connection: Upgrade\r\n"
17360 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417361
17362 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17363 arraysize(data_writes));
17364 session_deps_.socket_factory->AddSocketDataProvider(&data);
17365
17366 session->http_auth_cache()->Add(
17367 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17368 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17369
Bence Béky8d1c6052018-02-07 12:48:1517370 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17371
bnc87dcefc2017-05-25 12:47:5817372 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917373 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417374 trans->SetWebSocketHandshakeStreamCreateHelper(
17375 &websocket_stream_create_helper);
17376
17377 TestCompletionCallback callback;
17378
tfarina42834112016-09-22 13:38:2017379 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417381
17382 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117383 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417384
17385 const HttpResponseInfo* response = trans->GetResponseInfo();
17386 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217387 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417388
17389 EXPECT_EQ(101, response->headers->response_code());
17390
17391 trans.reset();
17392 session->CloseAllConnections();
17393}
17394
Bence Békydca6bd92018-01-30 13:43:0617395#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17396
bncd16676a2016-07-20 16:23:0117397TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917398 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217399 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917400 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217401 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217402
17403 HttpRequestInfo request;
17404 request.method = "POST";
17405 request.url = GURL("http://www.foo.com/");
17406 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017407 request.traffic_annotation =
17408 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217409
danakj1fd259a02016-04-16 03:17:0917410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217412 MockWrite data_writes[] = {
17413 MockWrite("POST / HTTP/1.1\r\n"
17414 "Host: www.foo.com\r\n"
17415 "Connection: keep-alive\r\n"
17416 "Content-Length: 3\r\n\r\n"),
17417 MockWrite("foo"),
17418 };
17419
17420 MockRead data_reads[] = {
17421 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17422 MockRead(SYNCHRONOUS, OK),
17423 };
17424 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17425 arraysize(data_writes));
17426 session_deps_.socket_factory->AddSocketDataProvider(&data);
17427
17428 TestCompletionCallback callback;
17429
17430 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017431 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117432 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217433
17434 std::string response_data;
bnc691fda62016-08-12 00:43:1617435 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217436
17437 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617438 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217439 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617440 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217441}
17442
bncd16676a2016-07-20 16:23:0117443TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917444 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217445 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917446 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217447 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217448
17449 HttpRequestInfo request;
17450 request.method = "POST";
17451 request.url = GURL("http://www.foo.com/");
17452 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017453 request.traffic_annotation =
17454 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217455
danakj1fd259a02016-04-16 03:17:0917456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217458 MockWrite data_writes[] = {
17459 MockWrite("POST / HTTP/1.1\r\n"
17460 "Host: www.foo.com\r\n"
17461 "Connection: keep-alive\r\n"
17462 "Content-Length: 3\r\n\r\n"),
17463 MockWrite("foo"),
17464 };
17465
17466 MockRead data_reads[] = {
17467 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17468 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17469 MockRead(SYNCHRONOUS, OK),
17470 };
17471 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17472 arraysize(data_writes));
17473 session_deps_.socket_factory->AddSocketDataProvider(&data);
17474
17475 TestCompletionCallback callback;
17476
17477 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017478 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117479 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217480
17481 std::string response_data;
bnc691fda62016-08-12 00:43:1617482 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217483
17484 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617485 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217486 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617487 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217488}
17489
bncd16676a2016-07-20 16:23:0117490TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217491 ChunkedUploadDataStream upload_data_stream(0);
17492
17493 HttpRequestInfo request;
17494 request.method = "POST";
17495 request.url = GURL("http://www.foo.com/");
17496 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017497 request.traffic_annotation =
17498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217499
danakj1fd259a02016-04-16 03:17:0917500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217502 // Send headers successfully, but get an error while sending the body.
17503 MockWrite data_writes[] = {
17504 MockWrite("POST / HTTP/1.1\r\n"
17505 "Host: www.foo.com\r\n"
17506 "Connection: keep-alive\r\n"
17507 "Transfer-Encoding: chunked\r\n\r\n"),
17508 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17509 };
17510
17511 MockRead data_reads[] = {
17512 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17513 MockRead(SYNCHRONOUS, OK),
17514 };
17515 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17516 arraysize(data_writes));
17517 session_deps_.socket_factory->AddSocketDataProvider(&data);
17518
17519 TestCompletionCallback callback;
17520
17521 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017522 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217523
17524 base::RunLoop().RunUntilIdle();
17525 upload_data_stream.AppendData("f", 1, false);
17526
17527 base::RunLoop().RunUntilIdle();
17528 upload_data_stream.AppendData("oo", 2, true);
17529
robpercival214763f2016-07-01 23:27:0117530 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217531
17532 std::string response_data;
bnc691fda62016-08-12 00:43:1617533 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217534
17535 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617536 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217537 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617538 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217539}
17540
rdsmith1d343be52016-10-21 20:37:5017541// Confirm that transactions whose throttle is created in (and stays in)
17542// the unthrottled state are not blocked.
17543TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17544 TestNetworkStreamThrottler* throttler(nullptr);
17545 std::unique_ptr<HttpNetworkSession> session(
17546 CreateSessionWithThrottler(&session_deps_, &throttler));
17547
17548 // Send a simple request and make sure it goes through.
17549 HttpRequestInfo request;
17550 request.method = "GET";
17551 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017552 request.traffic_annotation =
17553 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017554
bnc87dcefc2017-05-25 12:47:5817555 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917556 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017557
17558 MockWrite data_writes[] = {
17559 MockWrite("GET / HTTP/1.1\r\n"
17560 "Host: www.example.org\r\n"
17561 "Connection: keep-alive\r\n\r\n"),
17562 };
17563 MockRead data_reads[] = {
17564 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17565 MockRead(SYNCHRONOUS, OK),
17566 };
17567 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17568 arraysize(data_writes));
17569 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17570
17571 TestCompletionCallback callback;
17572 trans->Start(&request, callback.callback(), NetLogWithSource());
17573 EXPECT_EQ(OK, callback.WaitForResult());
17574}
17575
17576// Confirm requests can be blocked by a throttler, and are resumed
17577// when the throttle is unblocked.
17578TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17579 TestNetworkStreamThrottler* throttler(nullptr);
17580 std::unique_ptr<HttpNetworkSession> session(
17581 CreateSessionWithThrottler(&session_deps_, &throttler));
17582
17583 // Send a simple request and make sure it goes through.
17584 HttpRequestInfo request;
17585 request.method = "GET";
17586 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017587 request.traffic_annotation =
17588 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017589
17590 MockWrite data_writes[] = {
17591 MockWrite("GET / HTTP/1.1\r\n"
17592 "Host: www.example.org\r\n"
17593 "Connection: keep-alive\r\n\r\n"),
17594 };
17595 MockRead data_reads[] = {
17596 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17597 MockRead(SYNCHRONOUS, OK),
17598 };
17599 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17600 arraysize(data_writes));
17601 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17602
17603 // Start a request that will be throttled at start; confirm it
17604 // doesn't complete.
17605 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817606 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917607 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017608
17609 TestCompletionCallback callback;
17610 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17611 EXPECT_EQ(ERR_IO_PENDING, rv);
17612
17613 base::RunLoop().RunUntilIdle();
17614 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17615 EXPECT_FALSE(callback.have_result());
17616
17617 // Confirm the request goes on to complete when unthrottled.
17618 throttler->UnthrottleAllRequests();
17619 base::RunLoop().RunUntilIdle();
17620 ASSERT_TRUE(callback.have_result());
17621 EXPECT_EQ(OK, callback.WaitForResult());
17622}
17623
17624// Destroy a request while it's throttled.
17625TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17626 TestNetworkStreamThrottler* throttler(nullptr);
17627 std::unique_ptr<HttpNetworkSession> session(
17628 CreateSessionWithThrottler(&session_deps_, &throttler));
17629
17630 // Send a simple request and make sure it goes through.
17631 HttpRequestInfo request;
17632 request.method = "GET";
17633 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017634 request.traffic_annotation =
17635 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017636
17637 MockWrite data_writes[] = {
17638 MockWrite("GET / HTTP/1.1\r\n"
17639 "Host: www.example.org\r\n"
17640 "Connection: keep-alive\r\n\r\n"),
17641 };
17642 MockRead data_reads[] = {
17643 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17644 MockRead(SYNCHRONOUS, OK),
17645 };
17646 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17647 arraysize(data_writes));
17648 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17649
17650 // Start a request that will be throttled at start; confirm it
17651 // doesn't complete.
17652 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817653 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917654 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017655
17656 TestCompletionCallback callback;
17657 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17658 EXPECT_EQ(ERR_IO_PENDING, rv);
17659
17660 base::RunLoop().RunUntilIdle();
17661 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17662 EXPECT_FALSE(callback.have_result());
17663
17664 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17665 trans.reset();
17666 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17667}
17668
17669// Confirm the throttler receives SetPriority calls.
17670TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17671 TestNetworkStreamThrottler* throttler(nullptr);
17672 std::unique_ptr<HttpNetworkSession> session(
17673 CreateSessionWithThrottler(&session_deps_, &throttler));
17674
17675 // Send a simple request and make sure it goes through.
17676 HttpRequestInfo request;
17677 request.method = "GET";
17678 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017679 request.traffic_annotation =
17680 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017681
17682 MockWrite data_writes[] = {
17683 MockWrite("GET / HTTP/1.1\r\n"
17684 "Host: www.example.org\r\n"
17685 "Connection: keep-alive\r\n\r\n"),
17686 };
17687 MockRead data_reads[] = {
17688 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17689 MockRead(SYNCHRONOUS, OK),
17690 };
17691 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17692 arraysize(data_writes));
17693 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17694
17695 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917696 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017697 // Start the transaction to associate a throttle with it.
17698 TestCompletionCallback callback;
17699 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17700 EXPECT_EQ(ERR_IO_PENDING, rv);
17701
17702 EXPECT_EQ(0, throttler->num_set_priority_calls());
17703 trans->SetPriority(LOW);
17704 EXPECT_EQ(1, throttler->num_set_priority_calls());
17705 EXPECT_EQ(LOW, throttler->last_priority_set());
17706
17707 throttler->UnthrottleAllRequests();
17708 base::RunLoop().RunUntilIdle();
17709 ASSERT_TRUE(callback.have_result());
17710 EXPECT_EQ(OK, callback.WaitForResult());
17711}
17712
17713// Confirm that unthrottling from a SetPriority call by the
17714// throttler works properly.
17715TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17716 TestNetworkStreamThrottler* throttler(nullptr);
17717 std::unique_ptr<HttpNetworkSession> session(
17718 CreateSessionWithThrottler(&session_deps_, &throttler));
17719
17720 // Send a simple request and make sure it goes through.
17721 HttpRequestInfo request;
17722 request.method = "GET";
17723 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017724 request.traffic_annotation =
17725 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017726
17727 MockWrite data_writes[] = {
17728 MockWrite("GET / HTTP/1.1\r\n"
17729 "Host: www.example.org\r\n"
17730 "Connection: keep-alive\r\n\r\n"),
17731 };
17732 MockRead data_reads[] = {
17733 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17734 MockRead(SYNCHRONOUS, OK),
17735 };
17736 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17737 arraysize(data_writes));
17738 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17739
17740 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17741 data_writes, arraysize(data_writes));
17742 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17743
17744 // Start a request that will be throttled at start; confirm it
17745 // doesn't complete.
17746 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817747 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917748 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017749
17750 TestCompletionCallback callback;
17751 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17752 EXPECT_EQ(ERR_IO_PENDING, rv);
17753
17754 base::RunLoop().RunUntilIdle();
17755 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17756 EXPECT_FALSE(callback.have_result());
17757
17758 // Create a new request, call SetPriority on it to unthrottle,
17759 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917760 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017761 throttler->set_priority_change_closure(
17762 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17763 base::Unretained(throttler)));
17764
17765 // Start the transaction to associate a throttle with it.
17766 TestCompletionCallback callback1;
17767 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17768 EXPECT_EQ(ERR_IO_PENDING, rv);
17769
17770 trans1->SetPriority(IDLE);
17771
17772 base::RunLoop().RunUntilIdle();
17773 ASSERT_TRUE(callback.have_result());
17774 EXPECT_EQ(OK, callback.WaitForResult());
17775 ASSERT_TRUE(callback1.have_result());
17776 EXPECT_EQ(OK, callback1.WaitForResult());
17777}
17778
17779// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817780void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017781
17782// Confirm that destroying a transaction from a SetPriority call by the
17783// throttler works properly.
17784TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
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 Halavatib5e433e2018-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 // Arrange for the set priority call on the above transaction to delete
17828 // the transaction.
bnc87dcefc2017-05-25 12:47:5817829 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017830 throttler->set_priority_change_closure(
17831 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17832
17833 // Call it and check results (partially a "doesn't crash" test).
17834 trans_ptr->SetPriority(IDLE);
17835 trans_ptr = nullptr; // No longer a valid pointer.
17836
17837 base::RunLoop().RunUntilIdle();
17838 ASSERT_FALSE(callback.have_result());
17839}
17840
nharperb7441ef2016-01-25 23:54:1417841#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117842TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417843 const std::string https_url = "https://www.example.com";
17844 HttpRequestInfo request;
17845 request.url = GURL(https_url);
17846 request.method = "GET";
Ramin Halavatib5e433e2018-02-07 07:41:1017847 request.traffic_annotation =
17848 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417849
17850 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917851 ssl.ssl_info.token_binding_negotiated = true;
17852 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617853 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417854 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17855
bnc42331402016-07-25 13:36:1517856 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117857 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17858 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417859 MockRead(ASYNC, ERR_IO_PENDING)};
17860 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17861 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817862 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917863 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417865
17866 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17867 TestCompletionCallback callback;
17868 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017869 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017870
17871 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417872
17873 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17874 HttpRequestHeaders headers;
17875 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17876 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17877}
17878#endif // !defined(OS_IOS)
17879
eustasc7d27da2017-04-06 10:33:2017880void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17881 const std::string& accept_encoding,
17882 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317883 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017884 bool should_match) {
17885 HttpRequestInfo request;
17886 request.method = "GET";
17887 request.url = GURL("http://www.foo.com/");
17888 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17889 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017890 request.traffic_annotation =
17891 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017892
17893 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17894 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17895 // Send headers successfully, but get an error while sending the body.
17896 MockWrite data_writes[] = {
17897 MockWrite("GET / HTTP/1.1\r\n"
17898 "Host: www.foo.com\r\n"
17899 "Connection: keep-alive\r\n"
17900 "Accept-Encoding: "),
17901 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17902 };
17903
sky50576f32017-05-01 19:28:0317904 std::string response_code = "200 OK";
17905 std::string extra;
17906 if (!location.empty()) {
17907 response_code = "301 Redirect\r\nLocation: ";
17908 response_code.append(location);
17909 }
17910
eustasc7d27da2017-04-06 10:33:2017911 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317912 MockRead("HTTP/1.0 "),
17913 MockRead(response_code.data()),
17914 MockRead("\r\nContent-Encoding: "),
17915 MockRead(content_encoding.data()),
17916 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017917 MockRead(SYNCHRONOUS, OK),
17918 };
17919 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17920 arraysize(data_writes));
17921 session_deps->socket_factory->AddSocketDataProvider(&data);
17922
17923 TestCompletionCallback callback;
17924
17925 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17927
17928 rv = callback.WaitForResult();
17929 if (should_match) {
17930 EXPECT_THAT(rv, IsOk());
17931 } else {
17932 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17933 }
17934}
17935
17936TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317937 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017938}
17939
17940TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317941 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17942 true);
eustasc7d27da2017-04-06 10:33:2017943}
17944
17945TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17946 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317947 "", false);
17948}
17949
17950TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17951 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17952 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017953}
17954
xunjieli96f2a402017-06-05 17:24:2717955TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17956 ProxyConfig proxy_config;
17957 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17958 proxy_config.set_pac_mandatory(true);
17959 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917960 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917961 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17962 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0417963 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717964
17965 HttpRequestInfo request;
17966 request.method = "GET";
17967 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017968 request.traffic_annotation =
17969 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717970
17971 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17972 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17973
17974 TestCompletionCallback callback;
17975
17976 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17978 EXPECT_THAT(callback.WaitForResult(),
17979 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17980}
17981
17982TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17983 ProxyConfig proxy_config;
17984 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17985 proxy_config.set_pac_mandatory(true);
17986 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17987 new MockAsyncProxyResolverFactory(false);
17988 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917989 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917990 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17991 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5917992 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717993 HttpRequestInfo request;
17994 request.method = "GET";
17995 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017996 request.traffic_annotation =
17997 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717998
17999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18001
18002 TestCompletionCallback callback;
18003 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18005
18006 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18007 ERR_FAILED, &resolver);
18008 EXPECT_THAT(callback.WaitForResult(),
18009 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18010}
18011
18012TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918013 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918014 ProxyResolutionService::CreateFixedFromPacResult(
18015 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718016 session_deps_.enable_quic = false;
18017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18018
18019 HttpRequestInfo request;
18020 request.method = "GET";
18021 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018022 request.traffic_annotation =
18023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718024
18025 TestCompletionCallback callback;
18026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18027 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18028 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18029
18030 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18031}
18032
[email protected]89ceba9a2009-03-21 03:46:0618033} // namespace net