blob: 5156c8c6d5996607b09990b01dcaee111d320b46 [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"
[email protected]125ef482013-06-11 18:32:4726#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0527#include "base/strings/utf_string_conversions.h"
fdorayf33fede2017-05-11 21:18:1028#include "base/test/scoped_task_environment.h"
[email protected]f36a8132011-09-02 18:36:3329#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3530#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3531#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0732#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3333#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2535#include "net/base/load_timing_info.h"
36#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2437#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5038#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1539#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4040#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3141#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5242#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1543#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0644#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2145#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0846#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1147#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1648#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5349#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2450#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1251#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0052#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2953#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1954#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5755#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5256#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5657#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2458#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1359#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5360#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5761#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3862#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1963#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0764#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0065#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1966#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5167#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4668#include "net/log/test_net_log_entry.h"
69#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4070#include "net/proxy_resolution/mock_proxy_resolver.h"
71#include "net/proxy_resolution/proxy_config_service_fixed.h"
72#include "net/proxy_resolution/proxy_info.h"
73#include "net/proxy_resolution/proxy_resolver.h"
74#include "net/proxy_resolution/proxy_resolver_factory.h"
75#include "net/proxy_resolution/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4476#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1577#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0378#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4779#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0280#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0781#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0482#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4483#include "net/socket/socket_test_util.h"
84#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0685#include "net/spdy/chromium/spdy_session.h"
86#include "net/spdy/chromium/spdy_session_pool.h"
87#include "net/spdy/chromium/spdy_test_util_common.h"
88#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1489#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5790#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0391#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5792#include "net/ssl/ssl_config_service_defaults.h"
93#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5494#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1195#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0196#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1097#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:4398#include "net/test/test_data_directory.h"
[email protected]baee31a2018-01-18 06:10:2399#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44100#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06101#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18102#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52103#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15104#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27105#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52106
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37107#if defined(NTLM_PORTABLE)
108#include "base/base64.h"
109#include "net/ntlm/ntlm_test_data.h"
110#endif
111
robpercival214763f2016-07-01 23:27:01112using net::test::IsError;
113using net::test::IsOk;
114
[email protected]ad65a3e2013-12-25 18:18:01115using base::ASCIIToUTF16;
116
initial.commit586acc5fe2008-07-26 22:42:52117//-----------------------------------------------------------------------------
118
ttuttle859dc7a2015-04-23 19:42:29119namespace net {
120
[email protected]13c8a092010-07-29 06:15:44121namespace {
122
rdsmith1d343be52016-10-21 20:37:50123class TestNetworkStreamThrottler : public NetworkThrottleManager {
124 public:
125 TestNetworkStreamThrottler()
126 : throttle_new_requests_(false),
127 num_set_priority_calls_(0),
128 last_priority_set_(IDLE) {}
129
130 ~TestNetworkStreamThrottler() override {
131 EXPECT_TRUE(outstanding_throttles_.empty());
132 }
133
134 // NetworkThrottleManager
135 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
136 RequestPriority priority,
137 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58138 auto test_throttle =
Jeremy Roman0579ed62017-08-29 15:56:19139 std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50140 outstanding_throttles_.insert(test_throttle.get());
141 return std::move(test_throttle);
142 }
143
144 void UnthrottleAllRequests() {
145 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25146 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24147 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50148 throttle->Unthrottle();
149 }
150 }
151
152 void set_throttle_new_requests(bool throttle_new_requests) {
153 throttle_new_requests_ = throttle_new_requests;
154 }
155
156 // Includes both throttled and unthrottled throttles.
157 size_t num_outstanding_requests() const {
158 return outstanding_throttles_.size();
159 }
160
161 int num_set_priority_calls() const { return num_set_priority_calls_; }
162 RequestPriority last_priority_set() const { return last_priority_set_; }
163 void set_priority_change_closure(
164 const base::Closure& priority_change_closure) {
165 priority_change_closure_ = priority_change_closure;
166 }
167
168 private:
169 class TestThrottle : public NetworkThrottleManager::Throttle {
170 public:
171 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
172
173 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24174 bool IsBlocked() const override { return throttled_; }
175 RequestPriority Priority() const override {
176 NOTREACHED();
177 return IDLE;
178 }
rdsmith1d343be52016-10-21 20:37:50179 void SetPriority(RequestPriority priority) override {
180 throttler_->SetPriorityCalled(priority);
181 }
182
183 TestThrottle(bool throttled,
184 ThrottleDelegate* delegate,
185 TestNetworkStreamThrottler* throttler)
186 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
187
188 void Unthrottle() {
189 EXPECT_TRUE(throttled_);
190
191 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24192 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50193 }
194
195 bool throttled_;
196 ThrottleDelegate* delegate_;
197 TestNetworkStreamThrottler* throttler_;
198 };
199
200 void OnThrottleDestroyed(TestThrottle* throttle) {
201 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
202 outstanding_throttles_.erase(throttle);
203 }
204
205 void SetPriorityCalled(RequestPriority priority) {
206 ++num_set_priority_calls_;
207 last_priority_set_ = priority;
208 if (!priority_change_closure_.is_null())
209 priority_change_closure_.Run();
210 }
211
212 // Includes both throttled and unthrottled throttles.
213 std::set<TestThrottle*> outstanding_throttles_;
214 bool throttle_new_requests_;
215 int num_set_priority_calls_;
216 RequestPriority last_priority_set_;
217 base::Closure priority_change_closure_;
218
219 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
220};
221
[email protected]42cba2fb2013-03-29 19:58:57222const base::string16 kBar(ASCIIToUTF16("bar"));
223const base::string16 kBar2(ASCIIToUTF16("bar2"));
224const base::string16 kBar3(ASCIIToUTF16("bar3"));
225const base::string16 kBaz(ASCIIToUTF16("baz"));
226const base::string16 kFirst(ASCIIToUTF16("first"));
227const base::string16 kFoo(ASCIIToUTF16("foo"));
228const base::string16 kFoo2(ASCIIToUTF16("foo2"));
229const base::string16 kFoo3(ASCIIToUTF16("foo3"));
230const base::string16 kFou(ASCIIToUTF16("fou"));
231const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57232const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44233
bnc2df4b522016-07-08 18:17:43234const char kAlternativeServiceHttpHeader[] =
235 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
236
ttuttle859dc7a2015-04-23 19:42:29237int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
238 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
239 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02240}
241
ttuttle859dc7a2015-04-23 19:42:29242int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
243 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
244 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02245}
246
ttuttle859dc7a2015-04-23 19:42:29247bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
248 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
249 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52250}
251
[email protected]f3da152d2012-06-02 01:00:57252// Takes in a Value created from a NetLogHttpResponseParameter, and returns
253// a JSONified list of headers as a single string. Uses single quotes instead
254// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27255bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57256 if (!params)
257 return false;
[email protected]ea5ef4c2013-06-13 22:50:27258 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57259 if (!params->GetList("headers", &header_list))
260 return false;
261 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34262 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28263 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57264 return true;
265}
266
[email protected]029c83b62013-01-24 05:28:20267// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
268// used.
ttuttle859dc7a2015-04-23 19:42:29269void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20270 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19271 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25272
[email protected]029c83b62013-01-24 05:28:20273 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
274 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
275
ttuttle859dc7a2015-04-23 19:42:29276 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20277 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25278
279 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25280
[email protected]3b23a222013-05-15 21:33:25281 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25282 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
283 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25284 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25285}
286
[email protected]029c83b62013-01-24 05:28:20287// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
288// used.
ttuttle859dc7a2015-04-23 19:42:29289void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25290 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20291 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19292 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20293
294 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
295 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
296
ttuttle859dc7a2015-04-23 19:42:29297 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
298 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20299 EXPECT_LE(load_timing_info.connect_timing.connect_end,
300 load_timing_info.send_start);
301
302 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20303
[email protected]3b23a222013-05-15 21:33:25304 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20305 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
306 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25307 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20308}
309
310// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
311// used.
ttuttle859dc7a2015-04-23 19:42:29312void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20313 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19314 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20315
ttuttle859dc7a2015-04-23 19:42:29316 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20317
318 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
319 EXPECT_LE(load_timing_info.proxy_resolve_start,
320 load_timing_info.proxy_resolve_end);
321 EXPECT_LE(load_timing_info.proxy_resolve_end,
322 load_timing_info.send_start);
323 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20324
[email protected]3b23a222013-05-15 21:33:25325 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20326 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
327 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25328 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20329}
330
331// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
332// used.
ttuttle859dc7a2015-04-23 19:42:29333void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20334 int connect_timing_flags) {
335 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19336 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20337
338 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
339 EXPECT_LE(load_timing_info.proxy_resolve_start,
340 load_timing_info.proxy_resolve_end);
341 EXPECT_LE(load_timing_info.proxy_resolve_end,
342 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29343 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
344 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20345 EXPECT_LE(load_timing_info.connect_timing.connect_end,
346 load_timing_info.send_start);
347
348 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20349
[email protected]3b23a222013-05-15 21:33:25350 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20351 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
352 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25353 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25354}
355
danakj1fd259a02016-04-16 03:17:09356std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42357 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34358 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14359}
360
rdsmith1d343be52016-10-21 20:37:50361// Note that the pointer written into |*throttler| will only be valid
362// for the lifetime of the returned HttpNetworkSession.
363std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
364 SpdySessionDependencies* session_deps,
365 TestNetworkStreamThrottler** throttler) {
366 std::unique_ptr<HttpNetworkSession> session(
367 SpdySessionDependencies::SpdyCreateSession(session_deps));
368
Jeremy Roman0579ed62017-08-29 15:56:19369 auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50370 *throttler = owned_throttler.get();
371
372 HttpNetworkSessionPeer peer(session.get());
373 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
374
375 return session;
376}
377
xunjieli96f2a402017-06-05 17:24:27378class FailingProxyResolverFactory : public ProxyResolverFactory {
379 public:
380 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
381
382 // ProxyResolverFactory override.
383 int CreateProxyResolver(
384 const scoped_refptr<ProxyResolverScriptData>& script_data,
385 std::unique_ptr<ProxyResolver>* result,
386 const CompletionCallback& callback,
387 std::unique_ptr<Request>* request) override {
388 return ERR_PAC_SCRIPT_FAILED;
389 }
390};
391
[email protected]448d4ca52012-03-04 04:12:23392} // namespace
393
bncd16676a2016-07-20 16:23:01394class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03395 public:
bncd16676a2016-07-20 16:23:01396 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03397 // Important to restore the per-pool limit first, since the pool limit must
398 // always be greater than group limit, and the tests reduce both limits.
399 ClientSocketPoolManager::set_max_sockets_per_pool(
400 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
401 ClientSocketPoolManager::set_max_sockets_per_group(
402 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
403 }
404
[email protected]e3ceb682011-06-28 23:55:46405 protected:
[email protected]23e482282013-06-14 16:08:02406 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15407 : ssl_(ASYNC, OK),
408 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03409 HttpNetworkSession::NORMAL_SOCKET_POOL)),
410 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
411 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28412 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03413 }
[email protected]bb88e1d32013-05-03 23:11:07414
[email protected]e3ceb682011-06-28 23:55:46415 struct SimpleGetHelperResult {
416 int rv;
417 std::string status_line;
418 std::string response_data;
sclittlefb249892015-09-10 21:33:22419 int64_t total_received_bytes;
420 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25421 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47422 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59423 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46424 };
425
dcheng67be2b1f2014-10-27 21:47:29426 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50427 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55428 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54429 }
430
dcheng67be2b1f2014-10-27 21:47:29431 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50432 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55433 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09434 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55435 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09436 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50437 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55438 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09439 }
440
[email protected]202965992011-12-07 23:04:51441 // Either |write_failure| specifies a write failure or |read_failure|
442 // specifies a read failure when using a reused socket. In either case, the
443 // failure should cause the network transaction to resend the request, and the
444 // other argument should be NULL.
445 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
446 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52447
[email protected]a34f61ee2014-03-18 20:59:49448 // Either |write_failure| specifies a write failure or |read_failure|
449 // specifies a read failure when using a reused socket. In either case, the
450 // failure should cause the network transaction to resend the request, and the
451 // other argument should be NULL.
452 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10453 const MockRead* read_failure,
454 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49455
[email protected]5a60c8b2011-10-19 20:14:29456 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
457 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15458 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52459
[email protected]ff007e162009-05-23 09:13:15460 HttpRequestInfo request;
461 request.method = "GET";
bncce36dca22015-04-21 22:11:23462 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10463 request.traffic_annotation =
464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52465
vishal.b62985ca92015-04-17 08:45:51466 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07467 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27470
[email protected]5a60c8b2011-10-19 20:14:29471 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07472 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29473 }
initial.commit586acc5fe2008-07-26 22:42:52474
[email protected]49639fa2011-12-20 23:22:41475 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52476
eroman24bc6a12015-05-06 19:55:48477 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16478 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52480
[email protected]ff007e162009-05-23 09:13:15481 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16482 out.total_received_bytes = trans.GetTotalReceivedBytes();
483 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25484
485 // Even in the failure cases that use this function, connections are always
486 // successfully established before the error.
bnc691fda62016-08-12 00:43:16487 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25488 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
489
[email protected]ff007e162009-05-23 09:13:15490 if (out.rv != OK)
491 return out;
492
bnc691fda62016-08-12 00:43:16493 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50494 // Can't use ASSERT_* inside helper functions like this, so
495 // return an error.
wezca1070932016-05-26 20:30:52496 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50497 out.rv = ERR_UNEXPECTED;
498 return out;
499 }
[email protected]ff007e162009-05-23 09:13:15500 out.status_line = response->headers->GetStatusLine();
501
[email protected]80a09a82012-11-16 17:40:06502 EXPECT_EQ("127.0.0.1", response->socket_address.host());
503 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19504
ttuttled9dbc652015-09-29 20:00:59505 bool got_endpoint =
bnc691fda62016-08-12 00:43:16506 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59507 EXPECT_EQ(got_endpoint,
508 out.remote_endpoint_after_start.address().size() > 0);
509
bnc691fda62016-08-12 00:43:16510 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01511 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40512
mmenke43758e62015-05-04 21:09:46513 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40514 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39515 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00516 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
517 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39518 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00519 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
520 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15521
[email protected]f3da152d2012-06-02 01:00:57522 std::string line;
523 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
524 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
525
[email protected]79e1fd62013-06-20 06:50:04526 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16527 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04528 std::string value;
529 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23530 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04531 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
532 EXPECT_EQ("keep-alive", value);
533
534 std::string response_headers;
535 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23536 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04537 response_headers);
[email protected]3deb9a52010-11-11 00:24:40538
bnc691fda62016-08-12 00:43:16539 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22540 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16541 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22542
bnc691fda62016-08-12 00:43:16543 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47544 return out;
[email protected]ff007e162009-05-23 09:13:15545 }
initial.commit586acc5fe2008-07-26 22:42:52546
[email protected]5a60c8b2011-10-19 20:14:29547 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
548 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22549 MockWrite data_writes[] = {
550 MockWrite("GET / HTTP/1.1\r\n"
551 "Host: www.example.org\r\n"
552 "Connection: keep-alive\r\n\r\n"),
553 };
[email protected]5a60c8b2011-10-19 20:14:29554
sclittlefb249892015-09-10 21:33:22555 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
556 arraysize(data_writes));
557 StaticSocketDataProvider* data[] = {&reads};
558 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
559
560 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
561 out.total_sent_bytes);
562 return out;
[email protected]b8015c42013-12-24 15:18:19563 }
564
bnc032658ba2016-09-26 18:17:15565 void AddSSLSocketData() {
566 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49567 ssl_.ssl_info.cert =
568 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
569 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15570 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
571 }
572
[email protected]ff007e162009-05-23 09:13:15573 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
574 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52575
[email protected]ff007e162009-05-23 09:13:15576 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07577
578 void BypassHostCacheOnRefreshHelper(int load_flags);
579
580 void CheckErrorIsPassedBack(int error, IoMode mode);
581
[email protected]4bd46222013-05-14 19:32:23582 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07583 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15584 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03585
586 // Original socket limits. Some tests set these. Safest to always restore
587 // them once each test has been run.
588 int old_max_group_sockets_;
589 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15590};
[email protected]231d5a32008-09-13 00:45:27591
[email protected]448d4ca52012-03-04 04:12:23592namespace {
593
ryansturm49a8cb12016-06-15 16:51:09594class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27595 public:
ryansturm49a8cb12016-06-15 16:51:09596 BeforeHeadersSentHandler()
597 : observed_before_headers_sent_with_proxy_(false),
598 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27599
ryansturm49a8cb12016-06-15 16:51:09600 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
601 HttpRequestHeaders* request_headers) {
602 observed_before_headers_sent_ = true;
603 if (!proxy_info.is_http() && !proxy_info.is_https() &&
604 !proxy_info.is_quic()) {
605 return;
606 }
607 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27608 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
609 }
610
ryansturm49a8cb12016-06-15 16:51:09611 bool observed_before_headers_sent_with_proxy() const {
612 return observed_before_headers_sent_with_proxy_;
613 }
614
615 bool observed_before_headers_sent() const {
616 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27617 }
618
619 std::string observed_proxy_server_uri() const {
620 return observed_proxy_server_uri_;
621 }
622
623 private:
ryansturm49a8cb12016-06-15 16:51:09624 bool observed_before_headers_sent_with_proxy_;
625 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27626 std::string observed_proxy_server_uri_;
627
ryansturm49a8cb12016-06-15 16:51:09628 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27629};
630
[email protected]15a5ccf82008-10-23 19:57:43631// Fill |str| with a long header list that consumes >= |size| bytes.
632void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51633 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19634 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
635 const int sizeof_row = strlen(row);
636 const int num_rows = static_cast<int>(
637 ceil(static_cast<float>(size) / sizeof_row));
638 const int sizeof_data = num_rows * sizeof_row;
639 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43640 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51641
[email protected]4ddaf2502008-10-23 18:26:19642 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43643 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19644}
645
thakis84dff942015-07-28 20:47:38646#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09647uint64_t MockGetMSTime() {
648 // Tue, 23 May 2017 20:13:07 +0000
649 return 131400439870000000;
650}
651
[email protected]385a4672009-03-11 22:21:29652// Alternative functions that eliminate randomness and dependency on the local
653// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37654void MockGenerateRandom(uint8_t* output, size_t n) {
655 // This is set to 0xaa because the client challenge for testing in
656 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
657 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29658}
659
[email protected]fe2bc6a2009-03-23 16:52:20660std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37661 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29662}
thakis84dff942015-07-28 20:47:38663#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29664
[email protected]e60e47a2010-07-14 03:37:18665template<typename ParentPool>
666class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31667 public:
[email protected]9e1bdd32011-02-03 21:48:34668 CaptureGroupNameSocketPool(HostResolver* host_resolver,
669 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18670
[email protected]d80a4322009-08-14 07:07:49671 const std::string last_group_name_received() const {
672 return last_group_name_;
673 }
674
Tarun Bansal162eabe52018-01-20 01:16:39675 bool socket_requested() const { return socket_requested_; }
676
dmichaeld6e570d2014-12-18 22:30:57677 int RequestSocket(const std::string& group_name,
678 const void* socket_params,
679 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54680 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15681 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57682 ClientSocketHandle* handle,
683 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20684 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31685 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39686 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31687 return ERR_IO_PENDING;
688 }
dmichaeld6e570d2014-12-18 22:30:57689 void CancelRequest(const std::string& group_name,
690 ClientSocketHandle* handle) override {}
691 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09692 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57693 int id) override {}
694 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23695 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57696 int IdleSocketCount() const override { return 0; }
697 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31698 return 0;
699 }
dmichaeld6e570d2014-12-18 22:30:57700 LoadState GetLoadState(const std::string& group_name,
701 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31702 return LOAD_STATE_IDLE;
703 }
dmichaeld6e570d2014-12-18 22:30:57704 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26705 return base::TimeDelta();
706 }
[email protected]d80a4322009-08-14 07:07:49707
708 private:
[email protected]04e5be32009-06-26 20:00:31709 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39710 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31711};
712
[email protected]ab739042011-04-07 15:22:28713typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
714CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13715typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
716CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06717typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11718CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18719typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
720CaptureGroupNameSSLSocketPool;
721
rkaplowd90695c2015-03-25 22:12:41722template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18723CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34724 HostResolver* host_resolver,
725 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21726 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18727
hashimoto0d3e4fb2015-01-09 05:02:50728template <>
[email protected]2df19bb2010-08-25 20:13:46729CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21730 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34731 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09732 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46733
[email protected]007b3f82013-04-09 08:46:45734template <>
[email protected]e60e47a2010-07-14 03:37:18735CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21736 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34737 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45738 : SSLClientSocketPool(0,
739 0,
[email protected]007b3f82013-04-09 08:46:45740 cert_verifier,
741 NULL,
742 NULL,
[email protected]284303b62013-11-28 15:11:54743 NULL,
eranm6571b2b2014-12-03 15:53:23744 NULL,
[email protected]007b3f82013-04-09 08:46:45745 std::string(),
746 NULL,
747 NULL,
748 NULL,
749 NULL,
750 NULL,
[email protected]8e458552014-08-05 00:02:15751 NULL) {
752}
[email protected]2227c692010-05-04 15:36:11753
[email protected]231d5a32008-09-13 00:45:27754//-----------------------------------------------------------------------------
755
[email protected]79cb5c12011-09-12 13:12:04756// Helper functions for validating that AuthChallengeInfo's are correctly
757// configured for common cases.
758bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
759 if (!auth_challenge)
760 return false;
761 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43762 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04763 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19764 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04765 return true;
766}
767
768bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
769 if (!auth_challenge)
770 return false;
771 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43772 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
773 EXPECT_EQ("MyRealm1", auth_challenge->realm);
774 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
775 return true;
776}
777
778bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
779 if (!auth_challenge)
780 return false;
781 EXPECT_TRUE(auth_challenge->is_proxy);
782 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04783 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19784 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04785 return true;
786}
787
788bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
789 if (!auth_challenge)
790 return false;
791 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43792 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04793 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19794 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04795 return true;
796}
797
thakis84dff942015-07-28 20:47:38798#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04799bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
800 if (!auth_challenge)
801 return false;
802 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55803 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04804 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19805 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04806 return true;
807}
thakis84dff942015-07-28 20:47:38808#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04809
[email protected]448d4ca52012-03-04 04:12:23810} // namespace
811
bncd16676a2016-07-20 16:23:01812TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27815}
816
bncd16676a2016-07-20 16:23:01817TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27818 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35819 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
820 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06821 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27822 };
[email protected]31a2bfe2010-02-09 08:03:39823 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
824 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01825 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27826 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
827 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22828 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
829 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47830 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59831
832 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27833}
834
835// Response with no status line.
bncd16676a2016-07-20 16:23:01836TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27837 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35838 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06839 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27840 };
[email protected]31a2bfe2010-02-09 08:03:39841 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
842 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41843 EXPECT_THAT(out.rv, IsOk());
844 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
845 EXPECT_EQ("hello world", out.response_data);
846 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
847 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27848}
849
mmenkea7da6da2016-09-01 21:56:52850// Response with no status line, and a weird port. Should fail by default.
851TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
852 MockRead data_reads[] = {
853 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
854 };
855
856 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
857 session_deps_.socket_factory->AddSocketDataProvider(&data);
858
859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
860
krasinc06a72a2016-12-21 03:42:46861 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58862 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19863 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52864
mmenkea7da6da2016-09-01 21:56:52865 request.method = "GET";
866 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10867 request.traffic_annotation =
868 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
869
mmenkea7da6da2016-09-01 21:56:52870 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20871 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52872 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
873}
874
Shivani Sharmafdcaefd2017-11-02 00:12:26875// Tests that request info can be destroyed after the headers phase is complete.
876TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
878 auto trans =
879 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
880
881 MockRead data_reads[] = {
882 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
883 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
884 };
885 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
886 session_deps_.socket_factory->AddSocketDataProvider(&data);
887
888 TestCompletionCallback callback;
889
890 {
891 auto request = std::make_unique<HttpRequestInfo>();
892 request->method = "GET";
893 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10894 request->traffic_annotation =
895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26896
897 int rv =
898 trans->Start(request.get(), callback.callback(), NetLogWithSource());
899
900 EXPECT_THAT(callback.GetResult(rv), IsOk());
901 } // Let request info be destroyed.
902
903 trans.reset();
904}
905
mmenkea7da6da2016-09-01 21:56:52906// Response with no status line, and a weird port. Option to allow weird ports
907// enabled.
908TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
909 MockRead data_reads[] = {
910 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
911 };
912
913 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
914 session_deps_.socket_factory->AddSocketDataProvider(&data);
915 session_deps_.http_09_on_non_default_ports_enabled = true;
916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
917
krasinc06a72a2016-12-21 03:42:46918 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58919 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19920 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52921
mmenkea7da6da2016-09-01 21:56:52922 request.method = "GET";
923 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10924 request.traffic_annotation =
925 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
926
mmenkea7da6da2016-09-01 21:56:52927 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20928 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52929 EXPECT_THAT(callback.GetResult(rv), IsOk());
930
931 const HttpResponseInfo* info = trans->GetResponseInfo();
932 ASSERT_TRUE(info->headers);
933 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
934
935 // Don't bother to read the body - that's verified elsewhere, important thing
936 // is that the option to allow HTTP/0.9 on non-default ports is respected.
937}
938
[email protected]231d5a32008-09-13 00:45:27939// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01940TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27941 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35942 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06943 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27944 };
[email protected]31a2bfe2010-02-09 08:03:39945 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
946 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01947 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27948 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
949 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22950 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
951 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27952}
953
954// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01955TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27956 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35957 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06958 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27959 };
[email protected]31a2bfe2010-02-09 08:03:39960 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
961 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01962 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27963 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
964 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22965 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
966 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27967}
968
969// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01970TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27971 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35972 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06973 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27974 };
[email protected]31a2bfe2010-02-09 08:03:39975 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
976 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41977 EXPECT_THAT(out.rv, IsOk());
978 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
979 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
980 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
981 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27982}
983
984// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01985TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27986 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35987 MockRead("\n"),
988 MockRead("\n"),
989 MockRead("Q"),
990 MockRead("J"),
991 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06992 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27993 };
[email protected]31a2bfe2010-02-09 08:03:39994 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
995 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01996 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27997 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
998 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22999 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1000 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:271001}
1002
1003// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:011004TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:271005 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351006 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:061007 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:271008 };
[email protected]31a2bfe2010-02-09 08:03:391009 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1010 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411011 EXPECT_THAT(out.rv, IsOk());
1012 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1013 EXPECT_EQ("HTT", out.response_data);
1014 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1015 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521016}
1017
[email protected]f9d44aa2008-09-23 23:57:171018// Simulate a 204 response, lacking a Content-Length header, sent over a
1019// persistent connection. The response should still terminate since a 204
1020// cannot have a response body.
bncd16676a2016-07-20 16:23:011021TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191022 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171023 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351024 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191025 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061026 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171027 };
[email protected]31a2bfe2010-02-09 08:03:391028 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1029 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011030 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171031 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1032 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221033 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1034 int64_t response_size = reads_size - strlen(junk);
1035 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171036}
1037
[email protected]0877e3d2009-10-17 22:29:571038// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011039TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191040 std::string final_chunk = "0\r\n\r\n";
1041 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1042 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571043 MockRead data_reads[] = {
1044 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1045 MockRead("5\r\nHello\r\n"),
1046 MockRead("1\r\n"),
1047 MockRead(" \r\n"),
1048 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191049 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061050 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571051 };
[email protected]31a2bfe2010-02-09 08:03:391052 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1053 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571055 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1056 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221057 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1058 int64_t response_size = reads_size - extra_data.size();
1059 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571060}
1061
[email protected]9fe44f52010-09-23 18:36:001062// Next tests deal with http://crbug.com/56344.
1063
bncd16676a2016-07-20 16:23:011064TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001065 MultipleContentLengthHeadersNoTransferEncoding) {
1066 MockRead data_reads[] = {
1067 MockRead("HTTP/1.1 200 OK\r\n"),
1068 MockRead("Content-Length: 10\r\n"),
1069 MockRead("Content-Length: 5\r\n\r\n"),
1070 };
1071 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1072 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011073 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001074}
1075
bncd16676a2016-07-20 16:23:011076TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041077 DuplicateContentLengthHeadersNoTransferEncoding) {
1078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.1 200 OK\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n\r\n"),
1082 MockRead("Hello"),
1083 };
1084 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1085 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011086 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041087 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1088 EXPECT_EQ("Hello", out.response_data);
1089}
1090
bncd16676a2016-07-20 16:23:011091TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041092 ComplexContentLengthHeadersNoTransferEncoding) {
1093 // More than 2 dupes.
1094 {
1095 MockRead data_reads[] = {
1096 MockRead("HTTP/1.1 200 OK\r\n"),
1097 MockRead("Content-Length: 5\r\n"),
1098 MockRead("Content-Length: 5\r\n"),
1099 MockRead("Content-Length: 5\r\n\r\n"),
1100 MockRead("Hello"),
1101 };
1102 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1103 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011104 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041105 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1106 EXPECT_EQ("Hello", out.response_data);
1107 }
1108 // HTTP/1.0
1109 {
1110 MockRead data_reads[] = {
1111 MockRead("HTTP/1.0 200 OK\r\n"),
1112 MockRead("Content-Length: 5\r\n"),
1113 MockRead("Content-Length: 5\r\n"),
1114 MockRead("Content-Length: 5\r\n\r\n"),
1115 MockRead("Hello"),
1116 };
1117 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1118 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011119 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041120 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1121 EXPECT_EQ("Hello", out.response_data);
1122 }
1123 // 2 dupes and one mismatched.
1124 {
1125 MockRead data_reads[] = {
1126 MockRead("HTTP/1.1 200 OK\r\n"),
1127 MockRead("Content-Length: 10\r\n"),
1128 MockRead("Content-Length: 10\r\n"),
1129 MockRead("Content-Length: 5\r\n\r\n"),
1130 };
1131 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1132 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011133 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041134 }
1135}
1136
bncd16676a2016-07-20 16:23:011137TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001138 MultipleContentLengthHeadersTransferEncoding) {
1139 MockRead data_reads[] = {
1140 MockRead("HTTP/1.1 200 OK\r\n"),
1141 MockRead("Content-Length: 666\r\n"),
1142 MockRead("Content-Length: 1337\r\n"),
1143 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1144 MockRead("5\r\nHello\r\n"),
1145 MockRead("1\r\n"),
1146 MockRead(" \r\n"),
1147 MockRead("5\r\nworld\r\n"),
1148 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061149 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001150 };
1151 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1152 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011153 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001154 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1155 EXPECT_EQ("Hello world", out.response_data);
1156}
1157
[email protected]1628fe92011-10-04 23:04:551158// Next tests deal with http://crbug.com/98895.
1159
1160// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011161TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551162 MockRead data_reads[] = {
1163 MockRead("HTTP/1.1 200 OK\r\n"),
1164 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1165 MockRead("Content-Length: 5\r\n\r\n"),
1166 MockRead("Hello"),
1167 };
1168 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1169 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011170 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551171 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1172 EXPECT_EQ("Hello", out.response_data);
1173}
1174
[email protected]54a9c6e52012-03-21 20:10:591175// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011176TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551177 MockRead data_reads[] = {
1178 MockRead("HTTP/1.1 200 OK\r\n"),
1179 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1180 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1181 MockRead("Content-Length: 5\r\n\r\n"),
1182 MockRead("Hello"),
1183 };
1184 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1185 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011186 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591187 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1188 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551189}
1190
1191// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011192TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551193 MockRead data_reads[] = {
1194 MockRead("HTTP/1.1 200 OK\r\n"),
1195 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1196 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1197 MockRead("Content-Length: 5\r\n\r\n"),
1198 MockRead("Hello"),
1199 };
1200 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1201 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011202 EXPECT_THAT(out.rv,
1203 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551204}
1205
[email protected]54a9c6e52012-03-21 20:10:591206// Checks that two identical Location headers result in no error.
1207// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011208TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551209 MockRead data_reads[] = {
1210 MockRead("HTTP/1.1 302 Redirect\r\n"),
1211 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591212 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551213 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061214 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551215 };
1216
1217 HttpRequestInfo request;
1218 request.method = "GET";
1219 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101220 request.traffic_annotation =
1221 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551222
danakj1fd259a02016-04-16 03:17:091223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161224 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551225
1226 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071227 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551228
[email protected]49639fa2011-12-20 23:22:411229 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551230
tfarina42834112016-09-22 13:38:201231 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551233
robpercival214763f2016-07-01 23:27:011234 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551235
bnc691fda62016-08-12 00:43:161236 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521237 ASSERT_TRUE(response);
1238 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551239 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1240 std::string url;
1241 EXPECT_TRUE(response->headers->IsRedirect(&url));
1242 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471243 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551244}
1245
[email protected]1628fe92011-10-04 23:04:551246// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011247TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551248 MockRead data_reads[] = {
1249 MockRead("HTTP/1.1 302 Redirect\r\n"),
1250 MockRead("Location: http://good.com/\r\n"),
1251 MockRead("Location: http://evil.com/\r\n"),
1252 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061253 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551254 };
1255 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1256 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011257 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551258}
1259
[email protected]ef0faf2e72009-03-05 23:27:231260// Do a request using the HEAD method. Verify that we don't try to read the
1261// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011262TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421263 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231264 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231265 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101266 request.traffic_annotation =
1267 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231268
danakj1fd259a02016-04-16 03:17:091269 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161270 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091271 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161272 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091273 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1274 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271275
[email protected]ef0faf2e72009-03-05 23:27:231276 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131277 MockWrite("HEAD / HTTP/1.1\r\n"
1278 "Host: www.example.org\r\n"
1279 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231280 };
1281 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231282 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1283 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231284
mmenked39192ee2015-12-09 00:57:231285 // No response body because the test stops reading here.
1286 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231287 };
1288
[email protected]31a2bfe2010-02-09 08:03:391289 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1290 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071291 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231292
[email protected]49639fa2011-12-20 23:22:411293 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231294
tfarina42834112016-09-22 13:38:201295 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231297
1298 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011299 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231300
bnc691fda62016-08-12 00:43:161301 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521302 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231303
1304 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521305 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231306 EXPECT_EQ(1234, response->headers->GetContentLength());
1307 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471308 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091309 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1310 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231311
1312 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101313 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231314 bool has_server_header = response->headers->EnumerateHeader(
1315 &iter, "Server", &server_header);
1316 EXPECT_TRUE(has_server_header);
1317 EXPECT_EQ("Blah", server_header);
1318
1319 // Reading should give EOF right away, since there is no message body
1320 // (despite non-zero content-length).
1321 std::string response_data;
bnc691fda62016-08-12 00:43:161322 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011323 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231324 EXPECT_EQ("", response_data);
1325}
1326
bncd16676a2016-07-20 16:23:011327TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091328 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521329
1330 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351331 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1332 MockRead("hello"),
1333 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1334 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061335 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521336 };
[email protected]31a2bfe2010-02-09 08:03:391337 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071338 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521339
[email protected]0b0bf032010-09-21 18:08:501340 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521341 "hello", "world"
1342 };
1343
1344 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421345 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521346 request.method = "GET";
bncce36dca22015-04-21 22:11:231347 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101348 request.traffic_annotation =
1349 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521350
bnc691fda62016-08-12 00:43:161351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271352
[email protected]49639fa2011-12-20 23:22:411353 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521354
tfarina42834112016-09-22 13:38:201355 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521357
1358 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011359 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521360
bnc691fda62016-08-12 00:43:161361 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521362 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521363
wezca1070932016-05-26 20:30:521364 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251365 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471366 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521367
1368 std::string response_data;
bnc691fda62016-08-12 00:43:161369 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011370 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251371 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521372 }
1373}
1374
bncd16676a2016-07-20 16:23:011375TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091376 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221377 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191378 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221379 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271380
[email protected]1c773ea12009-04-28 19:58:421381 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521382 request.method = "POST";
1383 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271384 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101385 request.traffic_annotation =
1386 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521387
shivanishab9a143952016-09-19 17:23:411388 // Check the upload progress returned before initialization is correct.
1389 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1390 EXPECT_EQ(0u, progress.size());
1391 EXPECT_EQ(0u, progress.position());
1392
danakj1fd259a02016-04-16 03:17:091393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271395
initial.commit586acc5fe2008-07-26 22:42:521396 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351397 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1398 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1399 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061400 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521401 };
[email protected]31a2bfe2010-02-09 08:03:391402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071403 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521404
[email protected]49639fa2011-12-20 23:22:411405 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521406
tfarina42834112016-09-22 13:38:201407 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521409
1410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011411 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521412
bnc691fda62016-08-12 00:43:161413 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521414 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521415
wezca1070932016-05-26 20:30:521416 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251417 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521418
1419 std::string response_data;
bnc691fda62016-08-12 00:43:161420 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011421 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251422 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521423}
1424
[email protected]3a2d3662009-03-27 03:49:141425// This test is almost the same as Ignores100 above, but the response contains
1426// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571427// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011428TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421429 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141430 request.method = "GET";
1431 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101432 request.traffic_annotation =
1433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141434
danakj1fd259a02016-04-16 03:17:091435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271437
[email protected]3a2d3662009-03-27 03:49:141438 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571439 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1440 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141441 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061442 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141443 };
[email protected]31a2bfe2010-02-09 08:03:391444 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071445 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141446
[email protected]49639fa2011-12-20 23:22:411447 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141448
tfarina42834112016-09-22 13:38:201449 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141451
1452 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011453 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141454
bnc691fda62016-08-12 00:43:161455 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521456 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141457
wezca1070932016-05-26 20:30:521458 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141459 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1460
1461 std::string response_data;
bnc691fda62016-08-12 00:43:161462 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011463 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141464 EXPECT_EQ("hello world", response_data);
1465}
1466
bncd16676a2016-07-20 16:23:011467TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081468 HttpRequestInfo request;
1469 request.method = "POST";
1470 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101471 request.traffic_annotation =
1472 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081473
danakj1fd259a02016-04-16 03:17:091474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081476
1477 MockRead data_reads[] = {
1478 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1479 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381480 };
zmo9528c9f42015-08-04 22:12:081481 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1482 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381483
zmo9528c9f42015-08-04 22:12:081484 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381485
tfarina42834112016-09-22 13:38:201486 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381488
zmo9528c9f42015-08-04 22:12:081489 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011490 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381491
zmo9528c9f42015-08-04 22:12:081492 std::string response_data;
bnc691fda62016-08-12 00:43:161493 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011494 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081495 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381496}
1497
bncd16676a2016-07-20 16:23:011498TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381499 HttpRequestInfo request;
1500 request.method = "POST";
1501 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101502 request.traffic_annotation =
1503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381504
danakj1fd259a02016-04-16 03:17:091505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271507
[email protected]ee9410e72010-01-07 01:42:381508 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061509 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381510 };
[email protected]31a2bfe2010-02-09 08:03:391511 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071512 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381513
[email protected]49639fa2011-12-20 23:22:411514 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381515
tfarina42834112016-09-22 13:38:201516 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381518
1519 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011520 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381521}
1522
[email protected]23e482282013-06-14 16:08:021523void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511524 const MockWrite* write_failure,
1525 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421526 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521527 request.method = "GET";
1528 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101529 request.traffic_annotation =
1530 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521531
vishal.b62985ca92015-04-17 08:45:511532 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071533 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271535
[email protected]202965992011-12-07 23:04:511536 // Written data for successfully sending both requests.
1537 MockWrite data1_writes[] = {
1538 MockWrite("GET / HTTP/1.1\r\n"
1539 "Host: www.foo.com\r\n"
1540 "Connection: keep-alive\r\n\r\n"),
1541 MockWrite("GET / HTTP/1.1\r\n"
1542 "Host: www.foo.com\r\n"
1543 "Connection: keep-alive\r\n\r\n")
1544 };
1545
1546 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521547 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351548 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1549 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061550 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521551 };
[email protected]202965992011-12-07 23:04:511552
1553 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491554 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511555 data1_writes[1] = *write_failure;
1556 } else {
1557 ASSERT_TRUE(read_failure);
1558 data1_reads[2] = *read_failure;
1559 }
1560
1561 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1562 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071563 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521564
1565 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351566 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1567 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061568 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521569 };
[email protected]31a2bfe2010-02-09 08:03:391570 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071571 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521572
thestig9d3bb0c2015-01-24 00:49:511573 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521574 "hello", "world"
1575 };
1576
mikecironef22f9812016-10-04 03:40:191577 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521578 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411579 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521580
bnc691fda62016-08-12 00:43:161581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521582
tfarina42834112016-09-22 13:38:201583 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521585
1586 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011587 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521588
[email protected]58e32bb2013-01-21 18:23:251589 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161590 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251591 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1592 if (i == 0) {
1593 first_socket_log_id = load_timing_info.socket_log_id;
1594 } else {
1595 // The second request should be using a new socket.
1596 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1597 }
1598
bnc691fda62016-08-12 00:43:161599 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521600 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521601
wezca1070932016-05-26 20:30:521602 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471603 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251604 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521605
1606 std::string response_data;
bnc691fda62016-08-12 00:43:161607 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011608 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251609 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521610 }
1611}
[email protected]3d2a59b2008-09-26 19:44:251612
[email protected]a34f61ee2014-03-18 20:59:491613void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1614 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101615 const MockRead* read_failure,
1616 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491617 HttpRequestInfo request;
1618 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101619 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101620 request.traffic_annotation =
1621 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491622
vishal.b62985ca92015-04-17 08:45:511623 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491624 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491626
[email protected]09356c652014-03-25 15:36:101627 SSLSocketDataProvider ssl1(ASYNC, OK);
1628 SSLSocketDataProvider ssl2(ASYNC, OK);
1629 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361630 ssl1.next_proto = kProtoHTTP2;
1631 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101632 }
1633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491635
[email protected]09356c652014-03-25 15:36:101636 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411637 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491638 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411639 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151640 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411641 SpdySerializedFrame spdy_data(
1642 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491643
[email protected]09356c652014-03-25 15:36:101644 // HTTP/1.1 versions of the request and response.
1645 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1646 "Host: www.foo.com\r\n"
1647 "Connection: keep-alive\r\n\r\n";
1648 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1649 const char kHttpData[] = "hello";
1650
1651 std::vector<MockRead> data1_reads;
1652 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491653 if (write_failure) {
1654 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101655 data1_writes.push_back(*write_failure);
1656 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491657 } else {
1658 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101659 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411660 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101661 } else {
1662 data1_writes.push_back(MockWrite(kHttpRequest));
1663 }
1664 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491665 }
1666
[email protected]09356c652014-03-25 15:36:101667 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1668 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491669 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1670
[email protected]09356c652014-03-25 15:36:101671 std::vector<MockRead> data2_reads;
1672 std::vector<MockWrite> data2_writes;
1673
1674 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411675 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101676
bncdf80d44fd2016-07-15 20:27:411677 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1678 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101679 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1680 } else {
1681 data2_writes.push_back(
1682 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1683
1684 data2_reads.push_back(
1685 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1686 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1687 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1688 }
rch8e6c6c42015-05-01 14:05:131689 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1690 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491691 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1692
1693 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591694 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491695 // Wait for the preconnect to complete.
1696 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1697 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101698 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491699
1700 // Make the request.
1701 TestCompletionCallback callback;
1702
bnc691fda62016-08-12 00:43:161703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491704
tfarina42834112016-09-22 13:38:201705 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491707
1708 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011709 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491710
1711 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161712 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101713 TestLoadTimingNotReused(
1714 load_timing_info,
1715 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491716
bnc691fda62016-08-12 00:43:161717 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521718 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491719
wezca1070932016-05-26 20:30:521720 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021721 if (response->was_fetched_via_spdy) {
1722 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1723 } else {
1724 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1725 }
[email protected]a34f61ee2014-03-18 20:59:491726
1727 std::string response_data;
bnc691fda62016-08-12 00:43:161728 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011729 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101730 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491731}
1732
Biljith Jayan45a41722017-08-16 18:43:141733// Test that we do not retry indefinitely when a server sends an error like
1734// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1735// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1736TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1737 HttpRequestInfo request;
1738 request.method = "GET";
1739 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101740 request.traffic_annotation =
1741 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141742
1743 // Check whether we give up after the third try.
1744
1745 // Construct an HTTP2 request and a "Go away" response.
1746 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1747 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1748 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1749 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1750 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1751
1752 // Three go away responses.
1753 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1754 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1755 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1756
1757 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1758 AddSSLSocketData();
1759 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1760 AddSSLSocketData();
1761 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1762 AddSSLSocketData();
1763
1764 TestCompletionCallback callback;
1765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1767
1768 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1770
1771 rv = callback.WaitForResult();
1772 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1773}
1774
1775TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1776 HttpRequestInfo request;
1777 request.method = "GET";
1778 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101779 request.traffic_annotation =
1780 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141781
1782 // Check whether we try atleast thrice before giving up.
1783
1784 // Construct an HTTP2 request and a "Go away" response.
1785 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1786 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1787 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1788 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1789 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1790
1791 // Construct a non error HTTP2 response.
1792 SpdySerializedFrame spdy_response_no_error(
1793 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1794 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1795 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1796 CreateMockRead(spdy_data, 2)};
1797
1798 // Two error responses.
1799 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1800 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1801 // Followed by a success response.
1802 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1803
1804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1805 AddSSLSocketData();
1806 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1807 AddSSLSocketData();
1808 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1809 AddSSLSocketData();
1810
1811 TestCompletionCallback callback;
1812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1814
1815 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1817
1818 rv = callback.WaitForResult();
1819 EXPECT_THAT(rv, IsOk());
1820}
1821
bncd16676a2016-07-20 16:23:011822TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061823 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511824 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1825}
1826
bncd16676a2016-07-20 16:23:011827TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061828 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511829 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251830}
1831
bncd16676a2016-07-20 16:23:011832TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061833 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511834 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251835}
1836
[email protected]d58ceea82014-06-04 10:55:541837// Make sure that on a 408 response (Request Timeout), the request is retried,
1838// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011839TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541840 MockRead read_failure(SYNCHRONOUS,
1841 "HTTP/1.1 408 Request Timeout\r\n"
1842 "Connection: Keep-Alive\r\n"
1843 "Content-Length: 6\r\n\r\n"
1844 "Pickle");
1845 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1846}
1847
bncd16676a2016-07-20 16:23:011848TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491849 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101850 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491851}
1852
bncd16676a2016-07-20 16:23:011853TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491854 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101855 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491856}
1857
bncd16676a2016-07-20 16:23:011858TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491859 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101860 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1861}
1862
bncd16676a2016-07-20 16:23:011863TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101864 MockRead read_failure(ASYNC, OK); // EOF
1865 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1866}
1867
[email protected]d58ceea82014-06-04 10:55:541868// Make sure that on a 408 response (Request Timeout), the request is retried,
1869// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011870TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541871 MockRead read_failure(SYNCHRONOUS,
1872 "HTTP/1.1 408 Request Timeout\r\n"
1873 "Connection: Keep-Alive\r\n"
1874 "Content-Length: 6\r\n\r\n"
1875 "Pickle");
1876 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1877 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1878}
1879
bncd16676a2016-07-20 16:23:011880TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101881 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1882 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1883}
1884
bncd16676a2016-07-20 16:23:011885TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101886 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1887 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1888}
1889
bncd16676a2016-07-20 16:23:011890TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101891 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1892 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1893}
1894
bncd16676a2016-07-20 16:23:011895TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101896 MockRead read_failure(ASYNC, OK); // EOF
1897 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491898}
1899
bncd16676a2016-07-20 16:23:011900TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421901 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251902 request.method = "GET";
bncce36dca22015-04-21 22:11:231903 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101904 request.traffic_annotation =
1905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251906
danakj1fd259a02016-04-16 03:17:091907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161908 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271909
[email protected]3d2a59b2008-09-26 19:44:251910 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061911 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351912 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1913 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061914 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251915 };
[email protected]31a2bfe2010-02-09 08:03:391916 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071917 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251918
[email protected]49639fa2011-12-20 23:22:411919 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251920
tfarina42834112016-09-22 13:38:201921 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251923
1924 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011925 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591926
1927 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161928 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591929 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251930}
1931
1932// What do various browsers do when the server closes a non-keepalive
1933// connection without sending any response header or body?
1934//
1935// IE7: error page
1936// Safari 3.1.2 (Windows): error page
1937// Firefox 3.0.1: blank page
1938// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421939// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1940// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011941TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251942 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061943 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351944 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1945 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061946 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251947 };
[email protected]31a2bfe2010-02-09 08:03:391948 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1949 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011950 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251951}
[email protected]1826a402014-01-08 15:40:481952
[email protected]7a5378b2012-11-04 03:25:171953// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1954// tests. There was a bug causing HttpNetworkTransaction to hang in the
1955// destructor in such situations.
1956// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011957TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171958 HttpRequestInfo request;
1959 request.method = "GET";
bncce36dca22015-04-21 22:11:231960 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101961 request.traffic_annotation =
1962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171963
danakj1fd259a02016-04-16 03:17:091964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581965 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191966 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171967
1968 MockRead data_reads[] = {
1969 MockRead("HTTP/1.0 200 OK\r\n"),
1970 MockRead("Connection: keep-alive\r\n"),
1971 MockRead("Content-Length: 100\r\n\r\n"),
1972 MockRead("hello"),
1973 MockRead(SYNCHRONOUS, 0),
1974 };
1975 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071976 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171977
1978 TestCompletionCallback callback;
1979
tfarina42834112016-09-22 13:38:201980 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011981 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171982
1983 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011984 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171985
1986 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501987 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171988 if (rv == ERR_IO_PENDING)
1989 rv = callback.WaitForResult();
1990 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501991 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011992 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171993
1994 trans.reset();
fdoray92e35a72016-06-10 15:54:551995 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171996 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1997}
1998
bncd16676a2016-07-20 16:23:011999TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172000 HttpRequestInfo request;
2001 request.method = "GET";
bncce36dca22015-04-21 22:11:232002 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102003 request.traffic_annotation =
2004 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172005
danakj1fd259a02016-04-16 03:17:092006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582007 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192008 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172009
2010 MockRead data_reads[] = {
2011 MockRead("HTTP/1.0 200 OK\r\n"),
2012 MockRead("Connection: keep-alive\r\n"),
2013 MockRead("Content-Length: 100\r\n\r\n"),
2014 MockRead(SYNCHRONOUS, 0),
2015 };
2016 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072017 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172018
2019 TestCompletionCallback callback;
2020
tfarina42834112016-09-22 13:38:202021 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172023
2024 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012025 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172026
2027 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:502028 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172029 if (rv == ERR_IO_PENDING)
2030 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012031 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172032
2033 trans.reset();
fdoray92e35a72016-06-10 15:54:552034 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172035 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2036}
2037
[email protected]0b0bf032010-09-21 18:08:502038// Test that we correctly reuse a keep-alive connection after not explicitly
2039// reading the body.
bncd16676a2016-07-20 16:23:012040TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132041 HttpRequestInfo request;
2042 request.method = "GET";
2043 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102044 request.traffic_annotation =
2045 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132046
vishal.b62985ca92015-04-17 08:45:512047 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072048 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272050
mmenkecc2298e2015-12-07 18:20:182051 const char* request_data =
2052 "GET / HTTP/1.1\r\n"
2053 "Host: www.foo.com\r\n"
2054 "Connection: keep-alive\r\n\r\n";
2055 MockWrite data_writes[] = {
2056 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2057 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2058 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2059 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2060 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2061 };
2062
[email protected]0b0bf032010-09-21 18:08:502063 // Note that because all these reads happen in the same
2064 // StaticSocketDataProvider, it shows that the same socket is being reused for
2065 // all transactions.
mmenkecc2298e2015-12-07 18:20:182066 MockRead data_reads[] = {
2067 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2068 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2069 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2070 MockRead(ASYNC, 7,
2071 "HTTP/1.1 302 Found\r\n"
2072 "Content-Length: 0\r\n\r\n"),
2073 MockRead(ASYNC, 9,
2074 "HTTP/1.1 302 Found\r\n"
2075 "Content-Length: 5\r\n\r\n"
2076 "hello"),
2077 MockRead(ASYNC, 11,
2078 "HTTP/1.1 301 Moved Permanently\r\n"
2079 "Content-Length: 0\r\n\r\n"),
2080 MockRead(ASYNC, 13,
2081 "HTTP/1.1 301 Moved Permanently\r\n"
2082 "Content-Length: 5\r\n\r\n"
2083 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132084
mmenkecc2298e2015-12-07 18:20:182085 // In the next two rounds, IsConnectedAndIdle returns false, due to
2086 // the set_busy_before_sync_reads(true) call, while the
2087 // HttpNetworkTransaction is being shut down, but the socket is still
2088 // reuseable. See http://crbug.com/544255.
2089 MockRead(ASYNC, 15,
2090 "HTTP/1.1 200 Hunky-Dory\r\n"
2091 "Content-Length: 5\r\n\r\n"),
2092 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132093
mmenkecc2298e2015-12-07 18:20:182094 MockRead(ASYNC, 18,
2095 "HTTP/1.1 200 Hunky-Dory\r\n"
2096 "Content-Length: 5\r\n\r\n"
2097 "he"),
2098 MockRead(SYNCHRONOUS, 19, "llo"),
2099
2100 // The body of the final request is actually read.
2101 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2102 MockRead(ASYNC, 22, "hello"),
2103 };
2104 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2105 arraysize(data_writes));
2106 data.set_busy_before_sync_reads(true);
2107 session_deps_.socket_factory->AddSocketDataProvider(&data);
2108
2109 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502110 std::string response_lines[kNumUnreadBodies];
2111
mikecironef22f9812016-10-04 03:40:192112 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182113 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412114 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132115
Jeremy Roman0579ed62017-08-29 15:56:192116 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582117 session.get());
[email protected]fc31d6a42010-06-24 18:05:132118
tfarina42834112016-09-22 13:38:202119 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012120 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132121
[email protected]58e32bb2013-01-21 18:23:252122 LoadTimingInfo load_timing_info;
2123 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2124 if (i == 0) {
2125 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2126 first_socket_log_id = load_timing_info.socket_log_id;
2127 } else {
2128 TestLoadTimingReused(load_timing_info);
2129 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2130 }
2131
[email protected]fc31d6a42010-06-24 18:05:132132 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182133 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132134
mmenkecc2298e2015-12-07 18:20:182135 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502136 response_lines[i] = response->headers->GetStatusLine();
2137
mmenkecc2298e2015-12-07 18:20:182138 // Delete the transaction without reading the response bodies. Then spin
2139 // the message loop, so the response bodies are drained.
2140 trans.reset();
2141 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132142 }
[email protected]0b0bf032010-09-21 18:08:502143
2144 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182145 "HTTP/1.1 204 No Content",
2146 "HTTP/1.1 205 Reset Content",
2147 "HTTP/1.1 304 Not Modified",
2148 "HTTP/1.1 302 Found",
2149 "HTTP/1.1 302 Found",
2150 "HTTP/1.1 301 Moved Permanently",
2151 "HTTP/1.1 301 Moved Permanently",
2152 "HTTP/1.1 200 Hunky-Dory",
2153 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502154 };
2155
mostynb91e0da982015-01-20 19:17:272156 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2157 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502158
2159 for (int i = 0; i < kNumUnreadBodies; ++i)
2160 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2161
[email protected]49639fa2011-12-20 23:22:412162 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162163 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202164 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012165 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162166 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182167 ASSERT_TRUE(response);
2168 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502169 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2170 std::string response_data;
bnc691fda62016-08-12 00:43:162171 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012172 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502173 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132174}
2175
mmenke5f94fda2016-06-02 20:54:132176// Sockets that receive extra data after a response is complete should not be
2177// reused.
bncd16676a2016-07-20 16:23:012178TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2180 MockWrite data_writes1[] = {
2181 MockWrite("HEAD / HTTP/1.1\r\n"
2182 "Host: www.borked.com\r\n"
2183 "Connection: keep-alive\r\n\r\n"),
2184 };
2185
2186 MockRead data_reads1[] = {
2187 MockRead("HTTP/1.1 200 OK\r\n"
2188 "Connection: keep-alive\r\n"
2189 "Content-Length: 22\r\n\r\n"
2190 "This server is borked."),
2191 };
2192
2193 MockWrite data_writes2[] = {
2194 MockWrite("GET /foo HTTP/1.1\r\n"
2195 "Host: www.borked.com\r\n"
2196 "Connection: keep-alive\r\n\r\n"),
2197 };
2198
2199 MockRead data_reads2[] = {
2200 MockRead("HTTP/1.1 200 OK\r\n"
2201 "Content-Length: 3\r\n\r\n"
2202 "foo"),
2203 };
2204 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2205 data_writes1, arraysize(data_writes1));
2206 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2207 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2208 data_writes2, arraysize(data_writes2));
2209 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2210
2211 TestCompletionCallback callback;
2212 HttpRequestInfo request1;
2213 request1.method = "HEAD";
2214 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102215 request1.traffic_annotation =
2216 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132217
bnc87dcefc2017-05-25 12:47:582218 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192219 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202220 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012221 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132222
2223 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2224 ASSERT_TRUE(response1);
2225 ASSERT_TRUE(response1->headers);
2226 EXPECT_EQ(200, response1->headers->response_code());
2227 EXPECT_TRUE(response1->headers->IsKeepAlive());
2228
2229 std::string response_data1;
robpercival214763f2016-07-01 23:27:012230 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132231 EXPECT_EQ("", response_data1);
2232 // Deleting the transaction attempts to release the socket back into the
2233 // socket pool.
2234 trans1.reset();
2235
2236 HttpRequestInfo request2;
2237 request2.method = "GET";
2238 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102239 request2.traffic_annotation =
2240 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132241
bnc87dcefc2017-05-25 12:47:582242 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192243 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202244 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012245 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132246
2247 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2248 ASSERT_TRUE(response2);
2249 ASSERT_TRUE(response2->headers);
2250 EXPECT_EQ(200, response2->headers->response_code());
2251
2252 std::string response_data2;
robpercival214763f2016-07-01 23:27:012253 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132254 EXPECT_EQ("foo", response_data2);
2255}
2256
bncd16676a2016-07-20 16:23:012257TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132258 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2259 MockWrite data_writes1[] = {
2260 MockWrite("GET / HTTP/1.1\r\n"
2261 "Host: www.borked.com\r\n"
2262 "Connection: keep-alive\r\n\r\n"),
2263 };
2264
2265 MockRead data_reads1[] = {
2266 MockRead("HTTP/1.1 200 OK\r\n"
2267 "Connection: keep-alive\r\n"
2268 "Content-Length: 22\r\n\r\n"
2269 "This server is borked."
2270 "Bonus data!"),
2271 };
2272
2273 MockWrite data_writes2[] = {
2274 MockWrite("GET /foo HTTP/1.1\r\n"
2275 "Host: www.borked.com\r\n"
2276 "Connection: keep-alive\r\n\r\n"),
2277 };
2278
2279 MockRead data_reads2[] = {
2280 MockRead("HTTP/1.1 200 OK\r\n"
2281 "Content-Length: 3\r\n\r\n"
2282 "foo"),
2283 };
2284 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2285 data_writes1, arraysize(data_writes1));
2286 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2287 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2288 data_writes2, arraysize(data_writes2));
2289 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2290
2291 TestCompletionCallback callback;
2292 HttpRequestInfo request1;
2293 request1.method = "GET";
2294 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102295 request1.traffic_annotation =
2296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132297
bnc87dcefc2017-05-25 12:47:582298 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192299 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202300 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012301 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132302
2303 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2304 ASSERT_TRUE(response1);
2305 ASSERT_TRUE(response1->headers);
2306 EXPECT_EQ(200, response1->headers->response_code());
2307 EXPECT_TRUE(response1->headers->IsKeepAlive());
2308
2309 std::string response_data1;
robpercival214763f2016-07-01 23:27:012310 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132311 EXPECT_EQ("This server is borked.", response_data1);
2312 // Deleting the transaction attempts to release the socket back into the
2313 // socket pool.
2314 trans1.reset();
2315
2316 HttpRequestInfo request2;
2317 request2.method = "GET";
2318 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102319 request2.traffic_annotation =
2320 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132321
bnc87dcefc2017-05-25 12:47:582322 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192323 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202324 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012325 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132326
2327 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2328 ASSERT_TRUE(response2);
2329 ASSERT_TRUE(response2->headers);
2330 EXPECT_EQ(200, response2->headers->response_code());
2331
2332 std::string response_data2;
robpercival214763f2016-07-01 23:27:012333 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132334 EXPECT_EQ("foo", response_data2);
2335}
2336
bncd16676a2016-07-20 16:23:012337TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2339 MockWrite data_writes1[] = {
2340 MockWrite("GET / HTTP/1.1\r\n"
2341 "Host: www.borked.com\r\n"
2342 "Connection: keep-alive\r\n\r\n"),
2343 };
2344
2345 MockRead data_reads1[] = {
2346 MockRead("HTTP/1.1 200 OK\r\n"
2347 "Connection: keep-alive\r\n"
2348 "Transfer-Encoding: chunked\r\n\r\n"),
2349 MockRead("16\r\nThis server is borked.\r\n"),
2350 MockRead("0\r\n\r\nBonus data!"),
2351 };
2352
2353 MockWrite data_writes2[] = {
2354 MockWrite("GET /foo HTTP/1.1\r\n"
2355 "Host: www.borked.com\r\n"
2356 "Connection: keep-alive\r\n\r\n"),
2357 };
2358
2359 MockRead data_reads2[] = {
2360 MockRead("HTTP/1.1 200 OK\r\n"
2361 "Content-Length: 3\r\n\r\n"
2362 "foo"),
2363 };
2364 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2365 data_writes1, arraysize(data_writes1));
2366 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2367 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2368 data_writes2, arraysize(data_writes2));
2369 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2370
2371 TestCompletionCallback callback;
2372 HttpRequestInfo request1;
2373 request1.method = "GET";
2374 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102375 request1.traffic_annotation =
2376 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132377
bnc87dcefc2017-05-25 12:47:582378 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192379 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202380 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012381 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132382
2383 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2384 ASSERT_TRUE(response1);
2385 ASSERT_TRUE(response1->headers);
2386 EXPECT_EQ(200, response1->headers->response_code());
2387 EXPECT_TRUE(response1->headers->IsKeepAlive());
2388
2389 std::string response_data1;
robpercival214763f2016-07-01 23:27:012390 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132391 EXPECT_EQ("This server is borked.", response_data1);
2392 // Deleting the transaction attempts to release the socket back into the
2393 // socket pool.
2394 trans1.reset();
2395
2396 HttpRequestInfo request2;
2397 request2.method = "GET";
2398 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102399 request2.traffic_annotation =
2400 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132401
bnc87dcefc2017-05-25 12:47:582402 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192403 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202404 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012405 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132406
2407 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2408 ASSERT_TRUE(response2);
2409 ASSERT_TRUE(response2->headers);
2410 EXPECT_EQ(200, response2->headers->response_code());
2411
2412 std::string response_data2;
robpercival214763f2016-07-01 23:27:012413 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132414 EXPECT_EQ("foo", response_data2);
2415}
2416
2417// This is a little different from the others - it tests the case that the
2418// HttpStreamParser doesn't know if there's extra data on a socket or not when
2419// the HttpNetworkTransaction is torn down, because the response body hasn't
2420// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012421TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2423 MockWrite data_writes1[] = {
2424 MockWrite("GET / HTTP/1.1\r\n"
2425 "Host: www.borked.com\r\n"
2426 "Connection: keep-alive\r\n\r\n"),
2427 };
2428
2429 MockRead data_reads1[] = {
2430 MockRead("HTTP/1.1 200 OK\r\n"
2431 "Connection: keep-alive\r\n"
2432 "Transfer-Encoding: chunked\r\n\r\n"),
2433 MockRead("16\r\nThis server is borked.\r\n"),
2434 MockRead("0\r\n\r\nBonus data!"),
2435 };
2436 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2437 data_writes1, arraysize(data_writes1));
2438 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2439
2440 TestCompletionCallback callback;
2441 HttpRequestInfo request1;
2442 request1.method = "GET";
2443 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102444 request1.traffic_annotation =
2445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132446
bnc87dcefc2017-05-25 12:47:582447 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192448 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582449 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012450 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132451
bnc87dcefc2017-05-25 12:47:582452 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132453 ASSERT_TRUE(response1);
2454 ASSERT_TRUE(response1->headers);
2455 EXPECT_EQ(200, response1->headers->response_code());
2456 EXPECT_TRUE(response1->headers->IsKeepAlive());
2457
2458 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2459 // response body.
bnc87dcefc2017-05-25 12:47:582460 trans.reset();
mmenke5f94fda2016-06-02 20:54:132461
2462 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2463 // socket can't be reused, rather than returning it to the socket pool.
2464 base::RunLoop().RunUntilIdle();
2465
2466 // There should be no idle sockets in the pool.
2467 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2468}
2469
[email protected]038e9a32008-10-08 22:40:162470// Test the request-challenge-retry sequence for basic auth.
2471// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012472TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422473 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162474 request.method = "GET";
bncce36dca22015-04-21 22:11:232475 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102476 request.traffic_annotation =
2477 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162478
vishal.b62985ca92015-04-17 08:45:512479 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072480 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272483
[email protected]f9ee6b52008-11-08 06:46:232484 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232485 MockWrite(
2486 "GET / HTTP/1.1\r\n"
2487 "Host: www.example.org\r\n"
2488 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232489 };
2490
[email protected]038e9a32008-10-08 22:40:162491 MockRead data_reads1[] = {
2492 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2493 // Give a couple authenticate options (only the middle one is actually
2494 // supported).
[email protected]22927ad2009-09-21 19:56:192495 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162496 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2497 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2498 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2499 // Large content-length -- won't matter, as connection will be reset.
2500 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062501 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162502 };
2503
2504 // After calling trans->RestartWithAuth(), this is the request we should
2505 // be issuing -- the final header line contains the credentials.
2506 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232507 MockWrite(
2508 "GET / HTTP/1.1\r\n"
2509 "Host: www.example.org\r\n"
2510 "Connection: keep-alive\r\n"
2511 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162512 };
2513
2514 // Lastly, the server responds with the actual content.
2515 MockRead data_reads2[] = {
2516 MockRead("HTTP/1.0 200 OK\r\n"),
2517 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2518 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062519 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162520 };
2521
[email protected]31a2bfe2010-02-09 08:03:392522 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2523 data_writes1, arraysize(data_writes1));
2524 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2525 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072526 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2527 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162528
[email protected]49639fa2011-12-20 23:22:412529 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162530
tfarina42834112016-09-22 13:38:202531 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162533
2534 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012535 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162536
[email protected]58e32bb2013-01-21 18:23:252537 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162538 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252539 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2540
sclittlefb249892015-09-10 21:33:222541 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162542 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222543 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162544 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192545
bnc691fda62016-08-12 00:43:162546 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522547 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042548 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162549
[email protected]49639fa2011-12-20 23:22:412550 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162551
bnc691fda62016-08-12 00:43:162552 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162554
2555 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012556 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162557
[email protected]58e32bb2013-01-21 18:23:252558 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162559 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252560 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2561 // The load timing after restart should have a new socket ID, and times after
2562 // those of the first load timing.
2563 EXPECT_LE(load_timing_info1.receive_headers_end,
2564 load_timing_info2.connect_timing.connect_start);
2565 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2566
sclittlefb249892015-09-10 21:33:222567 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162568 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222569 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162570 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192571
bnc691fda62016-08-12 00:43:162572 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522573 ASSERT_TRUE(response);
2574 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162575 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162576}
2577
ttuttled9dbc652015-09-29 20:00:592578// Test the request-challenge-retry sequence for basic auth.
2579// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012580TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592581 HttpRequestInfo request;
2582 request.method = "GET";
2583 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102584 request.traffic_annotation =
2585 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592586
2587 TestNetLog log;
2588 MockHostResolver* resolver = new MockHostResolver();
2589 session_deps_.net_log = &log;
2590 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092591 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592593
2594 resolver->rules()->ClearRules();
2595 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2596
2597 MockWrite data_writes1[] = {
2598 MockWrite("GET / HTTP/1.1\r\n"
2599 "Host: www.example.org\r\n"
2600 "Connection: keep-alive\r\n\r\n"),
2601 };
2602
2603 MockRead data_reads1[] = {
2604 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2605 // Give a couple authenticate options (only the middle one is actually
2606 // supported).
2607 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2608 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2609 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2610 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2611 // Large content-length -- won't matter, as connection will be reset.
2612 MockRead("Content-Length: 10000\r\n\r\n"),
2613 MockRead(SYNCHRONOUS, ERR_FAILED),
2614 };
2615
2616 // After calling trans->RestartWithAuth(), this is the request we should
2617 // be issuing -- the final header line contains the credentials.
2618 MockWrite data_writes2[] = {
2619 MockWrite("GET / HTTP/1.1\r\n"
2620 "Host: www.example.org\r\n"
2621 "Connection: keep-alive\r\n"
2622 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2623 };
2624
2625 // Lastly, the server responds with the actual content.
2626 MockRead data_reads2[] = {
2627 MockRead("HTTP/1.0 200 OK\r\n"),
2628 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2629 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2630 };
2631
2632 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2633 data_writes1, arraysize(data_writes1));
2634 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2635 data_writes2, arraysize(data_writes2));
2636 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2637 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2638
2639 TestCompletionCallback callback1;
2640
bnc691fda62016-08-12 00:43:162641 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202642 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592643
2644 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162645 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592646 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2647
2648 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162649 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592650 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162651 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592652
bnc691fda62016-08-12 00:43:162653 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592654 ASSERT_TRUE(response);
2655 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2656
2657 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162658 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592659 ASSERT_FALSE(endpoint.address().empty());
2660 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2661
2662 resolver->rules()->ClearRules();
2663 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2664
2665 TestCompletionCallback callback2;
2666
bnc691fda62016-08-12 00:43:162667 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592668 AuthCredentials(kFoo, kBar), callback2.callback())));
2669
2670 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162671 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592672 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2673 // The load timing after restart should have a new socket ID, and times after
2674 // those of the first load timing.
2675 EXPECT_LE(load_timing_info1.receive_headers_end,
2676 load_timing_info2.connect_timing.connect_start);
2677 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2678
2679 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162680 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592681 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162682 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592683
bnc691fda62016-08-12 00:43:162684 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592685 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522686 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592687 EXPECT_EQ(100, response->headers->GetContentLength());
2688
bnc691fda62016-08-12 00:43:162689 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592690 ASSERT_FALSE(endpoint.address().empty());
2691 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2692}
2693
bncd16676a2016-07-20 16:23:012694TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462695 HttpRequestInfo request;
2696 request.method = "GET";
bncce36dca22015-04-21 22:11:232697 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292698 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102699 request.traffic_annotation =
2700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462701
danakj1fd259a02016-04-16 03:17:092702 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272704
[email protected]861fcd52009-08-26 02:33:462705 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232706 MockWrite(
2707 "GET / HTTP/1.1\r\n"
2708 "Host: www.example.org\r\n"
2709 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462710 };
2711
2712 MockRead data_reads[] = {
2713 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2714 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2715 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2716 // Large content-length -- won't matter, as connection will be reset.
2717 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062718 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462719 };
2720
[email protected]31a2bfe2010-02-09 08:03:392721 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2722 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072723 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412724 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462725
tfarina42834112016-09-22 13:38:202726 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462728
2729 rv = callback.WaitForResult();
2730 EXPECT_EQ(0, rv);
2731
sclittlefb249892015-09-10 21:33:222732 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162733 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222734 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162735 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192736
bnc691fda62016-08-12 00:43:162737 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522738 ASSERT_TRUE(response);
2739 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462740}
2741
[email protected]2d2697f92009-02-18 21:00:322742// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2743// connection.
bncd16676a2016-07-20 16:23:012744TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182745 // On the second pass, the body read of the auth challenge is synchronous, so
2746 // IsConnectedAndIdle returns false. The socket should still be drained and
2747 // reused. See http://crbug.com/544255.
2748 for (int i = 0; i < 2; ++i) {
2749 HttpRequestInfo request;
2750 request.method = "GET";
2751 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102752 request.traffic_annotation =
2753 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322754
mmenkecc2298e2015-12-07 18:20:182755 TestNetLog log;
2756 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272758
mmenkecc2298e2015-12-07 18:20:182759 MockWrite data_writes[] = {
2760 MockWrite(ASYNC, 0,
2761 "GET / HTTP/1.1\r\n"
2762 "Host: www.example.org\r\n"
2763 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322764
bnc691fda62016-08-12 00:43:162765 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182766 // be issuing -- the final header line contains the credentials.
2767 MockWrite(ASYNC, 6,
2768 "GET / HTTP/1.1\r\n"
2769 "Host: www.example.org\r\n"
2770 "Connection: keep-alive\r\n"
2771 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2772 };
[email protected]2d2697f92009-02-18 21:00:322773
mmenkecc2298e2015-12-07 18:20:182774 MockRead data_reads[] = {
2775 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2776 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2777 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2778 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2779 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322780
mmenkecc2298e2015-12-07 18:20:182781 // Lastly, the server responds with the actual content.
2782 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2783 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2784 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2785 MockRead(ASYNC, 10, "Hello"),
2786 };
[email protected]2d2697f92009-02-18 21:00:322787
mmenkecc2298e2015-12-07 18:20:182788 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2789 arraysize(data_writes));
2790 data.set_busy_before_sync_reads(true);
2791 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462792
mmenkecc2298e2015-12-07 18:20:182793 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322794
bnc691fda62016-08-12 00:43:162795 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202796 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012797 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322798
mmenkecc2298e2015-12-07 18:20:182799 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162800 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182801 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322802
bnc691fda62016-08-12 00:43:162803 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182804 ASSERT_TRUE(response);
2805 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322806
mmenkecc2298e2015-12-07 18:20:182807 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252808
bnc691fda62016-08-12 00:43:162809 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2810 callback2.callback());
robpercival214763f2016-07-01 23:27:012811 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322812
mmenkecc2298e2015-12-07 18:20:182813 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162814 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182815 TestLoadTimingReused(load_timing_info2);
2816 // The load timing after restart should have the same socket ID, and times
2817 // those of the first load timing.
2818 EXPECT_LE(load_timing_info1.receive_headers_end,
2819 load_timing_info2.send_start);
2820 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322821
bnc691fda62016-08-12 00:43:162822 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182823 ASSERT_TRUE(response);
2824 EXPECT_FALSE(response->auth_challenge);
2825 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322826
mmenkecc2298e2015-12-07 18:20:182827 std::string response_data;
bnc691fda62016-08-12 00:43:162828 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322829
mmenkecc2298e2015-12-07 18:20:182830 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162831 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182832 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162833 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182834 }
[email protected]2d2697f92009-02-18 21:00:322835}
2836
2837// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2838// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012839TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422840 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322841 request.method = "GET";
bncce36dca22015-04-21 22:11:232842 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102843 request.traffic_annotation =
2844 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322845
danakj1fd259a02016-04-16 03:17:092846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272847
[email protected]2d2697f92009-02-18 21:00:322848 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162849 MockWrite("GET / HTTP/1.1\r\n"
2850 "Host: www.example.org\r\n"
2851 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322852
bnc691fda62016-08-12 00:43:162853 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232854 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162855 MockWrite("GET / HTTP/1.1\r\n"
2856 "Host: www.example.org\r\n"
2857 "Connection: keep-alive\r\n"
2858 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322859 };
2860
[email protected]2d2697f92009-02-18 21:00:322861 MockRead data_reads1[] = {
2862 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2863 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312864 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322865
2866 // Lastly, the server responds with the actual content.
2867 MockRead("HTTP/1.1 200 OK\r\n"),
2868 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502869 MockRead("Content-Length: 5\r\n\r\n"),
2870 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322871 };
2872
[email protected]2d0a4f92011-05-05 16:38:462873 // An incorrect reconnect would cause this to be read.
2874 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062875 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462876 };
2877
[email protected]31a2bfe2010-02-09 08:03:392878 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2879 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462880 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2881 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072882 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2883 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322884
[email protected]49639fa2011-12-20 23:22:412885 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322886
bnc691fda62016-08-12 00:43:162887 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202888 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322890
2891 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012892 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322893
bnc691fda62016-08-12 00:43:162894 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522895 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042896 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322897
[email protected]49639fa2011-12-20 23:22:412898 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322899
bnc691fda62016-08-12 00:43:162900 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322902
2903 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012904 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322905
bnc691fda62016-08-12 00:43:162906 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522907 ASSERT_TRUE(response);
2908 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502909 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322910}
2911
2912// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2913// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012914TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422915 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322916 request.method = "GET";
bncce36dca22015-04-21 22:11:232917 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102918 request.traffic_annotation =
2919 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322920
danakj1fd259a02016-04-16 03:17:092921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272922
[email protected]2d2697f92009-02-18 21:00:322923 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162924 MockWrite("GET / HTTP/1.1\r\n"
2925 "Host: www.example.org\r\n"
2926 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322927
bnc691fda62016-08-12 00:43:162928 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232929 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162930 MockWrite("GET / HTTP/1.1\r\n"
2931 "Host: www.example.org\r\n"
2932 "Connection: keep-alive\r\n"
2933 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322934 };
2935
2936 // Respond with 5 kb of response body.
2937 std::string large_body_string("Unauthorized");
2938 large_body_string.append(5 * 1024, ' ');
2939 large_body_string.append("\r\n");
2940
2941 MockRead data_reads1[] = {
2942 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2943 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2944 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2945 // 5134 = 12 + 5 * 1024 + 2
2946 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062947 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322948
2949 // Lastly, the server responds with the actual content.
2950 MockRead("HTTP/1.1 200 OK\r\n"),
2951 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502952 MockRead("Content-Length: 5\r\n\r\n"),
2953 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322954 };
2955
[email protected]2d0a4f92011-05-05 16:38:462956 // An incorrect reconnect would cause this to be read.
2957 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062958 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462959 };
2960
[email protected]31a2bfe2010-02-09 08:03:392961 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2962 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462963 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2964 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072965 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2966 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322967
[email protected]49639fa2011-12-20 23:22:412968 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322969
bnc691fda62016-08-12 00:43:162970 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202971 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322973
2974 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012975 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322976
bnc691fda62016-08-12 00:43:162977 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522978 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042979 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322980
[email protected]49639fa2011-12-20 23:22:412981 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322982
bnc691fda62016-08-12 00:43:162983 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322985
2986 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012987 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322988
bnc691fda62016-08-12 00:43:162989 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522990 ASSERT_TRUE(response);
2991 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502992 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322993}
2994
2995// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312996// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012997TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312998 HttpRequestInfo request;
2999 request.method = "GET";
bncce36dca22015-04-21 22:11:233000 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103001 request.traffic_annotation =
3002 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313003
danakj1fd259a02016-04-16 03:17:093004 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273005
[email protected]11203f012009-11-12 23:02:313006 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233007 MockWrite(
3008 "GET / HTTP/1.1\r\n"
3009 "Host: www.example.org\r\n"
3010 "Connection: keep-alive\r\n\r\n"),
3011 // This simulates the seemingly successful write to a closed connection
3012 // if the bug is not fixed.
3013 MockWrite(
3014 "GET / HTTP/1.1\r\n"
3015 "Host: www.example.org\r\n"
3016 "Connection: keep-alive\r\n"
3017 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313018 };
3019
3020 MockRead data_reads1[] = {
3021 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3022 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3023 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3024 MockRead("Content-Length: 14\r\n\r\n"),
3025 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063026 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313027 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063028 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313029 };
3030
bnc691fda62016-08-12 00:43:163031 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313032 // be issuing -- the final header line contains the credentials.
3033 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233034 MockWrite(
3035 "GET / HTTP/1.1\r\n"
3036 "Host: www.example.org\r\n"
3037 "Connection: keep-alive\r\n"
3038 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313039 };
3040
3041 // Lastly, the server responds with the actual content.
3042 MockRead data_reads2[] = {
3043 MockRead("HTTP/1.1 200 OK\r\n"),
3044 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503045 MockRead("Content-Length: 5\r\n\r\n"),
3046 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313047 };
3048
[email protected]31a2bfe2010-02-09 08:03:393049 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3050 data_writes1, arraysize(data_writes1));
3051 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3052 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073053 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3054 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313055
[email protected]49639fa2011-12-20 23:22:413056 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313057
bnc691fda62016-08-12 00:43:163058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203059 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313061
3062 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013063 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313064
bnc691fda62016-08-12 00:43:163065 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523066 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043067 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313068
[email protected]49639fa2011-12-20 23:22:413069 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313070
bnc691fda62016-08-12 00:43:163071 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313073
3074 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013075 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313076
bnc691fda62016-08-12 00:43:163077 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523078 ASSERT_TRUE(response);
3079 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503080 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313081}
3082
[email protected]394816e92010-08-03 07:38:593083// Test the request-challenge-retry sequence for basic auth, over a connection
3084// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013085TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013086 HttpRequestInfo request;
3087 request.method = "GET";
bncce36dca22015-04-21 22:11:233088 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013089 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293090 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103091 request.traffic_annotation =
3092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013093
3094 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593095 session_deps_.proxy_resolution_service =
3096 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
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 =
3223 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513224 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073225 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093226 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273227
[email protected]394816e92010-08-03 07:38:593228 // Since we have proxy, should try to establish tunnel.
3229 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543230 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173231 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543232 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113233 };
3234
mmenkee71e15332015-10-07 16:39:543235 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083236 // connection.
3237 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543238 // No credentials.
3239 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3240 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3241 MockRead("Proxy-Connection: close\r\n\r\n"),
3242 };
mmenkee0b5c882015-08-26 20:29:113243
mmenkee71e15332015-10-07 16:39:543244 MockWrite data_writes2[] = {
3245 // After calling trans->RestartWithAuth(), this is the request we should
3246 // be issuing -- the final header line contains the credentials.
3247 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173248 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543249 "Proxy-Connection: keep-alive\r\n"
3250 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083251
mmenkee71e15332015-10-07 16:39:543252 MockWrite("GET / HTTP/1.1\r\n"
3253 "Host: www.example.org\r\n"
3254 "Connection: keep-alive\r\n\r\n"),
3255 };
3256
3257 MockRead data_reads2[] = {
3258 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3259
3260 MockRead("HTTP/1.1 200 OK\r\n"),
3261 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3262 MockRead("Content-Length: 5\r\n\r\n"),
3263 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593264 };
3265
3266 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3267 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073268 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543269 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3270 data_writes2, arraysize(data_writes2));
3271 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063272 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593274
[email protected]49639fa2011-12-20 23:22:413275 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593276
bnc87dcefc2017-05-25 12:47:583277 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193278 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503279
[email protected]49639fa2011-12-20 23:22:413280 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593282
3283 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013284 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463285 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403286 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593287 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003288 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3289 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593290 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403291 entries, pos,
mikecirone8b85c432016-09-08 19:11:003292 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3293 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593294
3295 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523296 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013297 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523298 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593299 EXPECT_EQ(407, response->headers->response_code());
3300 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043301 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593302
[email protected]029c83b62013-01-24 05:28:203303 LoadTimingInfo load_timing_info;
3304 // CONNECT requests and responses are handled at the connect job level, so
3305 // the transaction does not yet have a connection.
3306 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3307
[email protected]49639fa2011-12-20 23:22:413308 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593309
[email protected]49639fa2011-12-20 23:22:413310 rv = trans->RestartWithAuth(
3311 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593313
3314 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013315 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593316
3317 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523318 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593319
3320 EXPECT_TRUE(response->headers->IsKeepAlive());
3321 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503322 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593323 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3324
3325 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523326 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503327
[email protected]029c83b62013-01-24 05:28:203328 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3329 TestLoadTimingNotReusedWithPac(load_timing_info,
3330 CONNECT_TIMING_HAS_SSL_TIMES);
3331
[email protected]0b0bf032010-09-21 18:08:503332 trans.reset();
[email protected]102e27c2011-02-23 01:01:313333 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593334}
3335
[email protected]11203f012009-11-12 23:02:313336// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013337// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013338TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233339 // On the second pass, the body read of the auth challenge is synchronous, so
3340 // IsConnectedAndIdle returns false. The socket should still be drained and
3341 // reused. See http://crbug.com/544255.
3342 for (int i = 0; i < 2; ++i) {
3343 HttpRequestInfo request;
3344 request.method = "GET";
3345 request.url = GURL("https://www.example.org/");
3346 // Ensure that proxy authentication is attempted even
3347 // when the no authentication data flag is set.
3348 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103349 request.traffic_annotation =
3350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013351
mmenked39192ee2015-12-09 00:57:233352 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593353 session_deps_.proxy_resolution_service =
3354 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233355 BoundTestNetLog log;
3356 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013358
bnc691fda62016-08-12 00:43:163359 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013360
mmenked39192ee2015-12-09 00:57:233361 // Since we have proxy, should try to establish tunnel.
3362 MockWrite data_writes1[] = {
3363 MockWrite(ASYNC, 0,
3364 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3365 "Host: www.example.org:443\r\n"
3366 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013367
bnc691fda62016-08-12 00:43:163368 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233369 // be issuing -- the final header line contains the credentials.
3370 MockWrite(ASYNC, 3,
3371 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3372 "Host: www.example.org:443\r\n"
3373 "Proxy-Connection: keep-alive\r\n"
3374 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3375 };
ttuttle34f63b52015-03-05 04:33:013376
mmenked39192ee2015-12-09 00:57:233377 // The proxy responds to the connect with a 407, using a persistent
3378 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3379 MockRead data_reads1[] = {
3380 // No credentials.
3381 MockRead(ASYNC, 1,
3382 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3383 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3384 "Proxy-Connection: keep-alive\r\n"
3385 "Content-Length: 10\r\n\r\n"),
3386 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013387
mmenked39192ee2015-12-09 00:57:233388 // Wrong credentials (wrong password).
3389 MockRead(ASYNC, 4,
3390 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3391 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3392 "Proxy-Connection: keep-alive\r\n"
3393 "Content-Length: 10\r\n\r\n"),
3394 // No response body because the test stops reading here.
3395 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3396 };
ttuttle34f63b52015-03-05 04:33:013397
mmenked39192ee2015-12-09 00:57:233398 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3399 arraysize(data_writes1));
3400 data1.set_busy_before_sync_reads(true);
3401 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013402
mmenked39192ee2015-12-09 00:57:233403 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013404
bnc691fda62016-08-12 00:43:163405 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013406 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013407
mmenked39192ee2015-12-09 00:57:233408 TestNetLogEntry::List entries;
3409 log.GetEntries(&entries);
3410 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003411 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3412 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233413 ExpectLogContainsSomewhere(
3414 entries, pos,
mikecirone8b85c432016-09-08 19:11:003415 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3416 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013417
bnc691fda62016-08-12 00:43:163418 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233419 ASSERT_TRUE(response);
3420 ASSERT_TRUE(response->headers);
3421 EXPECT_TRUE(response->headers->IsKeepAlive());
3422 EXPECT_EQ(407, response->headers->response_code());
3423 EXPECT_EQ(10, response->headers->GetContentLength());
3424 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3425 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013426
mmenked39192ee2015-12-09 00:57:233427 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013428
mmenked39192ee2015-12-09 00:57:233429 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163430 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3431 callback2.callback());
robpercival214763f2016-07-01 23:27:013432 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013433
bnc691fda62016-08-12 00:43:163434 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233435 ASSERT_TRUE(response);
3436 ASSERT_TRUE(response->headers);
3437 EXPECT_TRUE(response->headers->IsKeepAlive());
3438 EXPECT_EQ(407, response->headers->response_code());
3439 EXPECT_EQ(10, response->headers->GetContentLength());
3440 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3441 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013442
mmenked39192ee2015-12-09 00:57:233443 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3444 // out of scope.
3445 session->CloseAllConnections();
3446 }
ttuttle34f63b52015-03-05 04:33:013447}
3448
3449// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3450// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013451TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233452 // On the second pass, the body read of the auth challenge is synchronous, so
3453 // IsConnectedAndIdle returns false. The socket should still be drained and
3454 // reused. See http://crbug.com/544255.
3455 for (int i = 0; i < 2; ++i) {
3456 HttpRequestInfo request;
3457 request.method = "GET";
3458 request.url = GURL("https://www.example.org/");
3459 // Ensure that proxy authentication is attempted even
3460 // when the no authentication data flag is set.
3461 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103462 request.traffic_annotation =
3463 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233464
3465 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593466 session_deps_.proxy_resolution_service =
3467 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233468 BoundTestNetLog log;
3469 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233471
bnc691fda62016-08-12 00:43:163472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233473
3474 // Since we have proxy, should try to establish tunnel.
3475 MockWrite data_writes1[] = {
3476 MockWrite(ASYNC, 0,
3477 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3478 "Host: www.example.org:443\r\n"
3479 "Proxy-Connection: keep-alive\r\n\r\n"),
3480
bnc691fda62016-08-12 00:43:163481 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233482 // be issuing -- the final header line contains the credentials.
3483 MockWrite(ASYNC, 3,
3484 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3485 "Host: www.example.org:443\r\n"
3486 "Proxy-Connection: keep-alive\r\n"
3487 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3488 };
3489
3490 // The proxy responds to the connect with a 407, using a persistent
3491 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3492 MockRead data_reads1[] = {
3493 // No credentials.
3494 MockRead(ASYNC, 1,
3495 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3496 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3497 "Content-Length: 10\r\n\r\n"),
3498 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3499
3500 // Wrong credentials (wrong password).
3501 MockRead(ASYNC, 4,
3502 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3503 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3504 "Content-Length: 10\r\n\r\n"),
3505 // No response body because the test stops reading here.
3506 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3507 };
3508
3509 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3510 arraysize(data_writes1));
3511 data1.set_busy_before_sync_reads(true);
3512 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3513
3514 TestCompletionCallback callback1;
3515
bnc691fda62016-08-12 00:43:163516 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013517 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233518
3519 TestNetLogEntry::List entries;
3520 log.GetEntries(&entries);
3521 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003522 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3523 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233524 ExpectLogContainsSomewhere(
3525 entries, pos,
mikecirone8b85c432016-09-08 19:11:003526 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3527 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233528
bnc691fda62016-08-12 00:43:163529 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233530 ASSERT_TRUE(response);
3531 ASSERT_TRUE(response->headers);
3532 EXPECT_TRUE(response->headers->IsKeepAlive());
3533 EXPECT_EQ(407, response->headers->response_code());
3534 EXPECT_EQ(10, response->headers->GetContentLength());
3535 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3536 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3537
3538 TestCompletionCallback callback2;
3539
3540 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163541 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3542 callback2.callback());
robpercival214763f2016-07-01 23:27:013543 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233544
bnc691fda62016-08-12 00:43:163545 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233546 ASSERT_TRUE(response);
3547 ASSERT_TRUE(response->headers);
3548 EXPECT_TRUE(response->headers->IsKeepAlive());
3549 EXPECT_EQ(407, response->headers->response_code());
3550 EXPECT_EQ(10, response->headers->GetContentLength());
3551 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3552 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3553
3554 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3555 // out of scope.
3556 session->CloseAllConnections();
3557 }
3558}
3559
3560// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3561// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3562// the case the server sends extra data on the original socket, so it can't be
3563// reused.
bncd16676a2016-07-20 16:23:013564TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273565 HttpRequestInfo request;
3566 request.method = "GET";
bncce36dca22015-04-21 22:11:233567 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273568 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293569 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103570 request.traffic_annotation =
3571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273572
[email protected]2d2697f92009-02-18 21:00:323573 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593574 session_deps_.proxy_resolution_service =
3575 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513576 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073577 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323579
[email protected]2d2697f92009-02-18 21:00:323580 // Since we have proxy, should try to establish tunnel.
3581 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233582 MockWrite(ASYNC, 0,
3583 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173584 "Host: www.example.org:443\r\n"
3585 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233586 };
[email protected]2d2697f92009-02-18 21:00:323587
mmenked39192ee2015-12-09 00:57:233588 // The proxy responds to the connect with a 407, using a persistent, but sends
3589 // extra data, so the socket cannot be reused.
3590 MockRead data_reads1[] = {
3591 // No credentials.
3592 MockRead(ASYNC, 1,
3593 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3594 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3595 "Content-Length: 10\r\n\r\n"),
3596 MockRead(SYNCHRONOUS, 2, "0123456789"),
3597 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3598 };
3599
3600 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233601 // After calling trans->RestartWithAuth(), this is the request we should
3602 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233603 MockWrite(ASYNC, 0,
3604 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173605 "Host: www.example.org:443\r\n"
3606 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233607 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3608
3609 MockWrite(ASYNC, 2,
3610 "GET / HTTP/1.1\r\n"
3611 "Host: www.example.org\r\n"
3612 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323613 };
3614
mmenked39192ee2015-12-09 00:57:233615 MockRead data_reads2[] = {
3616 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323617
mmenked39192ee2015-12-09 00:57:233618 MockRead(ASYNC, 3,
3619 "HTTP/1.1 200 OK\r\n"
3620 "Content-Type: text/html; charset=iso-8859-1\r\n"
3621 "Content-Length: 5\r\n\r\n"),
3622 // No response body because the test stops reading here.
3623 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323624 };
3625
mmenked39192ee2015-12-09 00:57:233626 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3627 arraysize(data_writes1));
3628 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073629 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233630 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3631 arraysize(data_writes2));
3632 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3633 SSLSocketDataProvider ssl(ASYNC, OK);
3634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323635
[email protected]49639fa2011-12-20 23:22:413636 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323637
bnc87dcefc2017-05-25 12:47:583638 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193639 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323640
mmenked39192ee2015-12-09 00:57:233641 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013642 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233643
mmenke43758e62015-05-04 21:09:463644 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403645 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393646 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003647 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3648 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393649 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403650 entries, pos,
mikecirone8b85c432016-09-08 19:11:003651 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3652 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323653
[email protected]1c773ea12009-04-28 19:58:423654 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243655 ASSERT_TRUE(response);
3656 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323657 EXPECT_TRUE(response->headers->IsKeepAlive());
3658 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423659 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043660 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323661
mmenked39192ee2015-12-09 00:57:233662 LoadTimingInfo load_timing_info;
3663 // CONNECT requests and responses are handled at the connect job level, so
3664 // the transaction does not yet have a connection.
3665 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3666
[email protected]49639fa2011-12-20 23:22:413667 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323668
mmenked39192ee2015-12-09 00:57:233669 rv =
3670 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013671 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323672
[email protected]2d2697f92009-02-18 21:00:323673 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233674 EXPECT_EQ(200, response->headers->response_code());
3675 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423676 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133677
mmenked39192ee2015-12-09 00:57:233678 // The password prompt info should not be set.
3679 EXPECT_FALSE(response->auth_challenge);
3680
3681 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3682 TestLoadTimingNotReusedWithPac(load_timing_info,
3683 CONNECT_TIMING_HAS_SSL_TIMES);
3684
3685 trans.reset();
[email protected]102e27c2011-02-23 01:01:313686 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323687}
3688
mmenkee71e15332015-10-07 16:39:543689// Test the case a proxy closes a socket while the challenge body is being
3690// drained.
bncd16676a2016-07-20 16:23:013691TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543692 HttpRequestInfo request;
3693 request.method = "GET";
3694 request.url = GURL("https://www.example.org/");
3695 // Ensure that proxy authentication is attempted even
3696 // when the no authentication data flag is set.
3697 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103698 request.traffic_annotation =
3699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543700
3701 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593702 session_deps_.proxy_resolution_service =
3703 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093704 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543705
bnc691fda62016-08-12 00:43:163706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543707
3708 // Since we have proxy, should try to establish tunnel.
3709 MockWrite data_writes1[] = {
3710 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173711 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543712 "Proxy-Connection: keep-alive\r\n\r\n"),
3713 };
3714
3715 // The proxy responds to the connect with a 407, using a persistent
3716 // connection.
3717 MockRead data_reads1[] = {
3718 // No credentials.
3719 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3720 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3721 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3722 // Server hands up in the middle of the body.
3723 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3724 };
3725
3726 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163727 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543728 // be issuing -- the final header line contains the credentials.
3729 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173730 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543731 "Proxy-Connection: keep-alive\r\n"
3732 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3733
3734 MockWrite("GET / HTTP/1.1\r\n"
3735 "Host: www.example.org\r\n"
3736 "Connection: keep-alive\r\n\r\n"),
3737 };
3738
3739 MockRead data_reads2[] = {
3740 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3741
3742 MockRead("HTTP/1.1 200 OK\r\n"),
3743 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3744 MockRead("Content-Length: 5\r\n\r\n"),
3745 MockRead(SYNCHRONOUS, "hello"),
3746 };
3747
3748 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3749 data_writes1, arraysize(data_writes1));
3750 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3751 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3752 data_writes2, arraysize(data_writes2));
3753 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3754 SSLSocketDataProvider ssl(ASYNC, OK);
3755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3756
3757 TestCompletionCallback callback;
3758
tfarina42834112016-09-22 13:38:203759 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013760 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543761
bnc691fda62016-08-12 00:43:163762 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543763 ASSERT_TRUE(response);
3764 ASSERT_TRUE(response->headers);
3765 EXPECT_TRUE(response->headers->IsKeepAlive());
3766 EXPECT_EQ(407, response->headers->response_code());
3767 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3768
bnc691fda62016-08-12 00:43:163769 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013770 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543771
bnc691fda62016-08-12 00:43:163772 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543773 ASSERT_TRUE(response);
3774 ASSERT_TRUE(response->headers);
3775 EXPECT_TRUE(response->headers->IsKeepAlive());
3776 EXPECT_EQ(200, response->headers->response_code());
3777 std::string body;
bnc691fda62016-08-12 00:43:163778 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543779 EXPECT_EQ("hello", body);
3780}
3781
[email protected]a8e9b162009-03-12 00:06:443782// Test that we don't read the response body when we fail to establish a tunnel,
3783// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013784TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273785 HttpRequestInfo request;
3786 request.method = "GET";
bncce36dca22015-04-21 22:11:233787 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103788 request.traffic_annotation =
3789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273790
[email protected]a8e9b162009-03-12 00:06:443791 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593792 session_deps_.proxy_resolution_service =
3793 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443794
danakj1fd259a02016-04-16 03:17:093795 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443796
bnc691fda62016-08-12 00:43:163797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443798
[email protected]a8e9b162009-03-12 00:06:443799 // Since we have proxy, should try to establish tunnel.
3800 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173801 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3802 "Host: www.example.org:443\r\n"
3803 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443804 };
3805
3806 // The proxy responds to the connect with a 407.
3807 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243808 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3809 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3810 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233811 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243812 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443813 };
3814
[email protected]31a2bfe2010-02-09 08:03:393815 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3816 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073817 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443818
[email protected]49639fa2011-12-20 23:22:413819 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443820
tfarina42834112016-09-22 13:38:203821 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443823
3824 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013825 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443826
bnc691fda62016-08-12 00:43:163827 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243828 ASSERT_TRUE(response);
3829 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443830 EXPECT_TRUE(response->headers->IsKeepAlive());
3831 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423832 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443833
3834 std::string response_data;
bnc691fda62016-08-12 00:43:163835 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013836 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183837
3838 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313839 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443840}
3841
ttuttle7933c112015-01-06 00:55:243842// Test that we don't pass extraneous headers from the proxy's response to the
3843// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013844TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243845 HttpRequestInfo request;
3846 request.method = "GET";
bncce36dca22015-04-21 22:11:233847 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103848 request.traffic_annotation =
3849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243850
3851 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593852 session_deps_.proxy_resolution_service =
3853 ProxyResolutionService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243854
danakj1fd259a02016-04-16 03:17:093855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243856
bnc691fda62016-08-12 00:43:163857 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243858
3859 // Since we have proxy, should try to establish tunnel.
3860 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173861 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3862 "Host: www.example.org:443\r\n"
3863 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243864 };
3865
3866 // The proxy responds to the connect with a 407.
3867 MockRead data_reads[] = {
3868 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3869 MockRead("X-Foo: bar\r\n"),
3870 MockRead("Set-Cookie: foo=bar\r\n"),
3871 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3872 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233873 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243874 };
3875
3876 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3877 arraysize(data_writes));
3878 session_deps_.socket_factory->AddSocketDataProvider(&data);
3879
3880 TestCompletionCallback callback;
3881
tfarina42834112016-09-22 13:38:203882 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243884
3885 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013886 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243887
bnc691fda62016-08-12 00:43:163888 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243889 ASSERT_TRUE(response);
3890 ASSERT_TRUE(response->headers);
3891 EXPECT_TRUE(response->headers->IsKeepAlive());
3892 EXPECT_EQ(407, response->headers->response_code());
3893 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3894 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3895 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3896
3897 std::string response_data;
bnc691fda62016-08-12 00:43:163898 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013899 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243900
3901 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3902 session->CloseAllConnections();
3903}
3904
[email protected]8fdbcd22010-05-05 02:54:523905// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3906// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013907TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523908 HttpRequestInfo request;
3909 request.method = "GET";
bncce36dca22015-04-21 22:11:233910 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103911 request.traffic_annotation =
3912 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523913
[email protected]cb9bf6ca2011-01-28 13:15:273914 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273917
[email protected]8fdbcd22010-05-05 02:54:523918 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233919 MockWrite(
3920 "GET / HTTP/1.1\r\n"
3921 "Host: www.example.org\r\n"
3922 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523923 };
3924
3925 MockRead data_reads1[] = {
3926 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3927 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3928 // Large content-length -- won't matter, as connection will be reset.
3929 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063930 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523931 };
3932
3933 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3934 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073935 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523936
[email protected]49639fa2011-12-20 23:22:413937 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523938
tfarina42834112016-09-22 13:38:203939 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523941
3942 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013943 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523944}
3945
[email protected]7a67a8152010-11-05 18:31:103946// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3947// through a non-authenticating proxy. The request should fail with
3948// ERR_UNEXPECTED_PROXY_AUTH.
3949// Note that it is impossible to detect if an HTTP server returns a 407 through
3950// a non-authenticating proxy - there is nothing to indicate whether the
3951// response came from the proxy or the server, so it is treated as if the proxy
3952// issued the challenge.
bncd16676a2016-07-20 16:23:013953TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273954 HttpRequestInfo request;
3955 request.method = "GET";
bncce36dca22015-04-21 22:11:233956 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103957 request.traffic_annotation =
3958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273959
Lily Houghton8c2f97d2018-01-22 05:06:593960 session_deps_.proxy_resolution_service =
3961 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513962 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073963 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103965
[email protected]7a67a8152010-11-05 18:31:103966 // Since we have proxy, should try to establish tunnel.
3967 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173968 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3969 "Host: www.example.org:443\r\n"
3970 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103971
rsleevidb16bb02015-11-12 23:47:173972 MockWrite("GET / HTTP/1.1\r\n"
3973 "Host: www.example.org\r\n"
3974 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103975 };
3976
3977 MockRead data_reads1[] = {
3978 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3979
3980 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3981 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3982 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063983 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103984 };
3985
3986 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3987 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063989 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103991
[email protected]49639fa2011-12-20 23:22:413992 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103993
bnc691fda62016-08-12 00:43:163994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103995
bnc691fda62016-08-12 00:43:163996 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103998
3999 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014000 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464001 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404002 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104003 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004004 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4005 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104006 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404007 entries, pos,
mikecirone8b85c432016-09-08 19:11:004008 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4009 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104010}
[email protected]2df19bb2010-08-25 20:13:464011
mmenke2a1781d2015-10-07 19:25:334012// Test a proxy auth scheme that allows default credentials and a proxy server
4013// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014014TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334015 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4016 HttpRequestInfo request;
4017 request.method = "GET";
4018 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104019 request.traffic_annotation =
4020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334021
4022 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594023 session_deps_.proxy_resolution_service =
4024 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334025
Jeremy Roman0579ed62017-08-29 15:56:194026 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334027 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194028 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334029 mock_handler->set_allows_default_credentials(true);
4030 auth_handler_factory->AddMockHandler(mock_handler.release(),
4031 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484032 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334033
4034 // Add NetLog just so can verify load timing information gets a NetLog ID.
4035 NetLog net_log;
4036 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094037 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334038
4039 // Since we have proxy, should try to establish tunnel.
4040 MockWrite data_writes1[] = {
4041 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174042 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334043 "Proxy-Connection: keep-alive\r\n\r\n"),
4044 };
4045
4046 // The proxy responds to the connect with a 407, using a non-persistent
4047 // connection.
4048 MockRead data_reads1[] = {
4049 // No credentials.
4050 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4051 MockRead("Proxy-Authenticate: Mock\r\n"),
4052 MockRead("Proxy-Connection: close\r\n\r\n"),
4053 };
4054
4055 // Since the first connection couldn't be reused, need to establish another
4056 // once given credentials.
4057 MockWrite data_writes2[] = {
4058 // After calling trans->RestartWithAuth(), this is the request we should
4059 // be issuing -- the final header line contains the credentials.
4060 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174061 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334062 "Proxy-Connection: keep-alive\r\n"
4063 "Proxy-Authorization: auth_token\r\n\r\n"),
4064
4065 MockWrite("GET / HTTP/1.1\r\n"
4066 "Host: www.example.org\r\n"
4067 "Connection: keep-alive\r\n\r\n"),
4068 };
4069
4070 MockRead data_reads2[] = {
4071 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4072
4073 MockRead("HTTP/1.1 200 OK\r\n"),
4074 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4075 MockRead("Content-Length: 5\r\n\r\n"),
4076 MockRead(SYNCHRONOUS, "hello"),
4077 };
4078
4079 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4080 data_writes1, arraysize(data_writes1));
4081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4082 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4083 data_writes2, arraysize(data_writes2));
4084 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4085 SSLSocketDataProvider ssl(ASYNC, OK);
4086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4087
bnc87dcefc2017-05-25 12:47:584088 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194089 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334090
4091 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204092 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014093 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334094
4095 const HttpResponseInfo* response = trans->GetResponseInfo();
4096 ASSERT_TRUE(response);
4097 ASSERT_TRUE(response->headers);
4098 EXPECT_FALSE(response->headers->IsKeepAlive());
4099 EXPECT_EQ(407, response->headers->response_code());
4100 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4101 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524102 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334103
4104 LoadTimingInfo load_timing_info;
4105 // CONNECT requests and responses are handled at the connect job level, so
4106 // the transaction does not yet have a connection.
4107 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4108
4109 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014110 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334111 response = trans->GetResponseInfo();
4112 ASSERT_TRUE(response);
4113 ASSERT_TRUE(response->headers);
4114 EXPECT_TRUE(response->headers->IsKeepAlive());
4115 EXPECT_EQ(200, response->headers->response_code());
4116 EXPECT_EQ(5, response->headers->GetContentLength());
4117 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4118
4119 // The password prompt info should not be set.
4120 EXPECT_FALSE(response->auth_challenge);
4121
4122 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4123 TestLoadTimingNotReusedWithPac(load_timing_info,
4124 CONNECT_TIMING_HAS_SSL_TIMES);
4125
4126 trans.reset();
4127 session->CloseAllConnections();
4128}
4129
4130// Test a proxy auth scheme that allows default credentials and a proxy server
4131// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014132TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334133 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4134 HttpRequestInfo request;
4135 request.method = "GET";
4136 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104137 request.traffic_annotation =
4138 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334139
4140 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594141 session_deps_.proxy_resolution_service =
4142 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334143
Jeremy Roman0579ed62017-08-29 15:56:194144 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334145 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194146 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334147 mock_handler->set_allows_default_credentials(true);
4148 auth_handler_factory->AddMockHandler(mock_handler.release(),
4149 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484150 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334151
4152 // Add NetLog just so can verify load timing information gets a NetLog ID.
4153 NetLog net_log;
4154 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094155 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334156
4157 // Should try to establish tunnel.
4158 MockWrite data_writes1[] = {
4159 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174160 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334161 "Proxy-Connection: keep-alive\r\n\r\n"),
4162
4163 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174164 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334165 "Proxy-Connection: keep-alive\r\n"
4166 "Proxy-Authorization: auth_token\r\n\r\n"),
4167 };
4168
4169 // The proxy responds to the connect with a 407, using a non-persistent
4170 // connection.
4171 MockRead data_reads1[] = {
4172 // No credentials.
4173 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4174 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4175 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4176 };
4177
4178 // Since the first connection was closed, need to establish another once given
4179 // credentials.
4180 MockWrite data_writes2[] = {
4181 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174182 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334183 "Proxy-Connection: keep-alive\r\n"
4184 "Proxy-Authorization: auth_token\r\n\r\n"),
4185
4186 MockWrite("GET / HTTP/1.1\r\n"
4187 "Host: www.example.org\r\n"
4188 "Connection: keep-alive\r\n\r\n"),
4189 };
4190
4191 MockRead data_reads2[] = {
4192 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4193
4194 MockRead("HTTP/1.1 200 OK\r\n"),
4195 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4196 MockRead("Content-Length: 5\r\n\r\n"),
4197 MockRead(SYNCHRONOUS, "hello"),
4198 };
4199
4200 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4201 data_writes1, arraysize(data_writes1));
4202 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4203 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4204 data_writes2, arraysize(data_writes2));
4205 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4206 SSLSocketDataProvider ssl(ASYNC, OK);
4207 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4208
bnc87dcefc2017-05-25 12:47:584209 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194210 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334211
4212 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204213 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014214 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334215
4216 const HttpResponseInfo* response = trans->GetResponseInfo();
4217 ASSERT_TRUE(response);
4218 ASSERT_TRUE(response->headers);
4219 EXPECT_TRUE(response->headers->IsKeepAlive());
4220 EXPECT_EQ(407, response->headers->response_code());
4221 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4222 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4223 EXPECT_FALSE(response->auth_challenge);
4224
4225 LoadTimingInfo load_timing_info;
4226 // CONNECT requests and responses are handled at the connect job level, so
4227 // the transaction does not yet have a connection.
4228 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4229
4230 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014231 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334232
4233 response = trans->GetResponseInfo();
4234 ASSERT_TRUE(response);
4235 ASSERT_TRUE(response->headers);
4236 EXPECT_TRUE(response->headers->IsKeepAlive());
4237 EXPECT_EQ(200, response->headers->response_code());
4238 EXPECT_EQ(5, response->headers->GetContentLength());
4239 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4240
4241 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524242 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334243
4244 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4245 TestLoadTimingNotReusedWithPac(load_timing_info,
4246 CONNECT_TIMING_HAS_SSL_TIMES);
4247
4248 trans.reset();
4249 session->CloseAllConnections();
4250}
4251
4252// Test a proxy auth scheme that allows default credentials and a proxy server
4253// that hangs up when credentials are initially sent, and hangs up again when
4254// they are retried.
bncd16676a2016-07-20 16:23:014255TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334256 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4257 HttpRequestInfo request;
4258 request.method = "GET";
4259 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104260 request.traffic_annotation =
4261 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334262
4263 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594264 session_deps_.proxy_resolution_service =
4265 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334266
Jeremy Roman0579ed62017-08-29 15:56:194267 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334268 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194269 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334270 mock_handler->set_allows_default_credentials(true);
4271 auth_handler_factory->AddMockHandler(mock_handler.release(),
4272 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484273 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334274
4275 // Add NetLog just so can verify load timing information gets a NetLog ID.
4276 NetLog net_log;
4277 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094278 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334279
4280 // Should try to establish tunnel.
4281 MockWrite data_writes1[] = {
4282 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174283 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334284 "Proxy-Connection: keep-alive\r\n\r\n"),
4285
4286 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174287 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334288 "Proxy-Connection: keep-alive\r\n"
4289 "Proxy-Authorization: auth_token\r\n\r\n"),
4290 };
4291
4292 // The proxy responds to the connect with a 407, and then hangs up after the
4293 // second request is sent.
4294 MockRead data_reads1[] = {
4295 // No credentials.
4296 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4297 MockRead("Content-Length: 0\r\n"),
4298 MockRead("Proxy-Connection: keep-alive\r\n"),
4299 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4300 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4301 };
4302
4303 // HttpNetworkTransaction sees a reused connection that was closed with
4304 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4305 // request.
4306 MockWrite data_writes2[] = {
4307 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174308 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334309 "Proxy-Connection: keep-alive\r\n\r\n"),
4310 };
4311
4312 // The proxy, having had more than enough of us, just hangs up.
4313 MockRead data_reads2[] = {
4314 // No credentials.
4315 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4316 };
4317
4318 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4319 data_writes1, arraysize(data_writes1));
4320 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4321 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4322 data_writes2, arraysize(data_writes2));
4323 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4324
bnc87dcefc2017-05-25 12:47:584325 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194326 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334327
4328 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204329 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014330 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334331
4332 const HttpResponseInfo* response = trans->GetResponseInfo();
4333 ASSERT_TRUE(response);
4334 ASSERT_TRUE(response->headers);
4335 EXPECT_TRUE(response->headers->IsKeepAlive());
4336 EXPECT_EQ(407, response->headers->response_code());
4337 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4338 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4339 EXPECT_FALSE(response->auth_challenge);
4340
4341 LoadTimingInfo load_timing_info;
4342 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4343
4344 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014345 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334346
4347 trans.reset();
4348 session->CloseAllConnections();
4349}
4350
4351// Test a proxy auth scheme that allows default credentials and a proxy server
4352// that hangs up when credentials are initially sent, and sends a challenge
4353// again they are retried.
bncd16676a2016-07-20 16:23:014354TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334355 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4356 HttpRequestInfo request;
4357 request.method = "GET";
4358 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104359 request.traffic_annotation =
4360 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334361
4362 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594363 session_deps_.proxy_resolution_service =
4364 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334365
Jeremy Roman0579ed62017-08-29 15:56:194366 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334367 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194368 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334369 mock_handler->set_allows_default_credentials(true);
4370 auth_handler_factory->AddMockHandler(mock_handler.release(),
4371 HttpAuth::AUTH_PROXY);
4372 // Add another handler for the second challenge. It supports default
4373 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194374 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334375 mock_handler->set_allows_default_credentials(true);
4376 auth_handler_factory->AddMockHandler(mock_handler.release(),
4377 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484378 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334379
4380 // Add NetLog just so can verify load timing information gets a NetLog ID.
4381 NetLog net_log;
4382 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094383 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334384
4385 // Should try to establish tunnel.
4386 MockWrite data_writes1[] = {
4387 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174388 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334389 "Proxy-Connection: keep-alive\r\n\r\n"),
4390 };
4391
4392 // The proxy responds to the connect with a 407, using a non-persistent
4393 // connection.
4394 MockRead data_reads1[] = {
4395 // No credentials.
4396 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4397 MockRead("Proxy-Authenticate: Mock\r\n"),
4398 MockRead("Proxy-Connection: close\r\n\r\n"),
4399 };
4400
4401 // Since the first connection was closed, need to establish another once given
4402 // credentials.
4403 MockWrite data_writes2[] = {
4404 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174405 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334406 "Proxy-Connection: keep-alive\r\n"
4407 "Proxy-Authorization: auth_token\r\n\r\n"),
4408 };
4409
4410 MockRead data_reads2[] = {
4411 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4412 MockRead("Proxy-Authenticate: Mock\r\n"),
4413 MockRead("Proxy-Connection: close\r\n\r\n"),
4414 };
4415
4416 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4417 data_writes1, arraysize(data_writes1));
4418 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4419 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4420 data_writes2, arraysize(data_writes2));
4421 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4422 SSLSocketDataProvider ssl(ASYNC, OK);
4423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4424
bnc87dcefc2017-05-25 12:47:584425 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194426 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334427
4428 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204429 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014430 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334431
4432 const HttpResponseInfo* response = trans->GetResponseInfo();
4433 ASSERT_TRUE(response);
4434 ASSERT_TRUE(response->headers);
4435 EXPECT_EQ(407, response->headers->response_code());
4436 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4437 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4438 EXPECT_FALSE(response->auth_challenge);
4439
4440 LoadTimingInfo load_timing_info;
4441 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4442
4443 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014444 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334445 response = trans->GetResponseInfo();
4446 ASSERT_TRUE(response);
4447 ASSERT_TRUE(response->headers);
4448 EXPECT_EQ(407, response->headers->response_code());
4449 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4450 EXPECT_TRUE(response->auth_challenge);
4451
4452 trans.reset();
4453 session->CloseAllConnections();
4454}
4455
asankae2257db2016-10-11 22:03:164456// A more nuanced test than GenerateAuthToken test which asserts that
4457// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4458// unnecessarily invalidated, and that if the server co-operates, the
4459// authentication handshake can continue with the same scheme but with a
4460// different identity.
4461TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4462 HttpRequestInfo request;
4463 request.method = "GET";
4464 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104465 request.traffic_annotation =
4466 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164467
Jeremy Roman0579ed62017-08-29 15:56:194468 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164469 auth_handler_factory->set_do_init_from_challenge(true);
4470
4471 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194472 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164473 mock_handler->set_allows_default_credentials(true);
4474 mock_handler->set_allows_explicit_credentials(true);
4475 mock_handler->set_connection_based(true);
4476 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4477 auth_handler_factory->AddMockHandler(mock_handler.release(),
4478 HttpAuth::AUTH_SERVER);
4479
4480 // Add another handler for the second challenge. It supports default
4481 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194482 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164483 mock_handler->set_allows_default_credentials(true);
4484 mock_handler->set_allows_explicit_credentials(true);
4485 mock_handler->set_connection_based(true);
4486 auth_handler_factory->AddMockHandler(mock_handler.release(),
4487 HttpAuth::AUTH_SERVER);
4488 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4489
4490 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4491
4492 MockWrite data_writes1[] = {
4493 MockWrite("GET / HTTP/1.1\r\n"
4494 "Host: www.example.org\r\n"
4495 "Connection: keep-alive\r\n\r\n"),
4496 };
4497
4498 MockRead data_reads1[] = {
4499 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4500 "WWW-Authenticate: Mock\r\n"
4501 "Connection: keep-alive\r\n\r\n"),
4502 };
4503
4504 // Identical to data_writes1[]. The AuthHandler encounters a
4505 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4506 // transaction procceds without an authorization header.
4507 MockWrite data_writes2[] = {
4508 MockWrite("GET / HTTP/1.1\r\n"
4509 "Host: www.example.org\r\n"
4510 "Connection: keep-alive\r\n\r\n"),
4511 };
4512
4513 MockRead data_reads2[] = {
4514 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4515 "WWW-Authenticate: Mock\r\n"
4516 "Connection: keep-alive\r\n\r\n"),
4517 };
4518
4519 MockWrite data_writes3[] = {
4520 MockWrite("GET / HTTP/1.1\r\n"
4521 "Host: www.example.org\r\n"
4522 "Connection: keep-alive\r\n"
4523 "Authorization: auth_token\r\n\r\n"),
4524 };
4525
4526 MockRead data_reads3[] = {
4527 MockRead("HTTP/1.1 200 OK\r\n"
4528 "Content-Length: 5\r\n"
4529 "Content-Type: text/plain\r\n"
4530 "Connection: keep-alive\r\n\r\n"
4531 "Hello"),
4532 };
4533
4534 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4535 data_writes1, arraysize(data_writes1));
4536 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4537
4538 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4539 data_writes2, arraysize(data_writes2));
4540 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4541
4542 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4543 data_writes3, arraysize(data_writes3));
4544 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4545
bnc87dcefc2017-05-25 12:47:584546 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194547 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164548
4549 TestCompletionCallback callback;
4550 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4551 EXPECT_THAT(callback.GetResult(rv), IsOk());
4552
4553 const HttpResponseInfo* response = trans->GetResponseInfo();
4554 ASSERT_TRUE(response);
4555 ASSERT_TRUE(response->headers);
4556 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4557
4558 // The following three tests assert that an authentication challenge was
4559 // received and that the stack is ready to respond to the challenge using
4560 // ambient credentials.
4561 EXPECT_EQ(401, response->headers->response_code());
4562 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4563 EXPECT_FALSE(response->auth_challenge);
4564
4565 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4566 EXPECT_THAT(callback.GetResult(rv), IsOk());
4567 response = trans->GetResponseInfo();
4568 ASSERT_TRUE(response);
4569 ASSERT_TRUE(response->headers);
4570
4571 // The following three tests assert that an authentication challenge was
4572 // received and that the stack needs explicit credentials before it is ready
4573 // to respond to the challenge.
4574 EXPECT_EQ(401, response->headers->response_code());
4575 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4576 EXPECT_TRUE(response->auth_challenge);
4577
4578 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4579 EXPECT_THAT(callback.GetResult(rv), IsOk());
4580 response = trans->GetResponseInfo();
4581 ASSERT_TRUE(response);
4582 ASSERT_TRUE(response->headers);
4583 EXPECT_EQ(200, response->headers->response_code());
4584
4585 trans.reset();
4586 session->CloseAllConnections();
4587}
4588
Matt Menked1eb6d42018-01-17 04:54:064589// Proxy resolver that returns a proxy with the same host and port for different
4590// schemes, based on the path of the URL being requests.
4591class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4592 public:
4593 SameProxyWithDifferentSchemesProxyResolver() {}
4594 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4595
4596 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4597
4598 static HostPortPair ProxyHostPortPair() {
4599 return HostPortPair::FromString(ProxyHostPortPairAsString());
4600 }
4601
4602 // ProxyResolver implementation.
4603 int GetProxyForURL(const GURL& url,
4604 ProxyInfo* results,
4605 const CompletionCallback& callback,
4606 std::unique_ptr<Request>* request,
4607 const NetLogWithSource& /*net_log*/) override {
4608 *results = ProxyInfo();
4609 if (url.path() == "/socks4") {
4610 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4611 return OK;
4612 }
4613 if (url.path() == "/socks5") {
4614 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4615 return OK;
4616 }
4617 if (url.path() == "/http") {
4618 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4619 return OK;
4620 }
4621 if (url.path() == "/https") {
4622 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4623 return OK;
4624 }
4625 NOTREACHED();
4626 return ERR_NOT_IMPLEMENTED;
4627 }
4628
4629 private:
4630 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4631};
4632
4633class SameProxyWithDifferentSchemesProxyResolverFactory
4634 : public ProxyResolverFactory {
4635 public:
4636 SameProxyWithDifferentSchemesProxyResolverFactory()
4637 : ProxyResolverFactory(false) {}
4638
4639 int CreateProxyResolver(
4640 const scoped_refptr<ProxyResolverScriptData>& pac_script,
4641 std::unique_ptr<ProxyResolver>* resolver,
4642 const CompletionCallback& callback,
4643 std::unique_ptr<Request>* request) override {
4644 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4645 return OK;
4646 }
4647
4648 private:
4649 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4650};
4651
4652// Check that when different proxy schemes are all applied to a proxy at the
4653// same address, the sonnections are not grouped together. i.e., a request to
4654// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4655// request to foo.com using proxy.com as an HTTP proxy.
4656TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Lily Houghton8c2f97d2018-01-22 05:06:594657 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Matt Menked1eb6d42018-01-17 04:54:064658 std::make_unique<ProxyConfigServiceFixed>(
4659 ProxyConfig::CreateAutoDetect()),
4660 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4661 nullptr);
4662
4663 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4664
4665 MockWrite socks_writes[] = {
4666 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4667 kSOCKS4OkRequestLocalHostPort80Length),
4668 MockWrite(SYNCHRONOUS,
4669 "GET /socks4 HTTP/1.1\r\n"
4670 "Host: test\r\n"
4671 "Connection: keep-alive\r\n\r\n"),
4672 };
4673 MockRead socks_reads[] = {
4674 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4675 MockRead("HTTP/1.0 200 OK\r\n"
4676 "Connection: keep-alive\r\n"
4677 "Content-Length: 15\r\n\r\n"
4678 "SOCKS4 Response"),
4679 };
4680 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4681 socks_writes, arraysize(socks_writes));
4682 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4683
4684 const char kSOCKS5Request[] = {
4685 0x05, // Version
4686 0x01, // Command (CONNECT)
4687 0x00, // Reserved
4688 0x03, // Address type (DOMAINNAME)
4689 0x04, // Length of domain (4)
4690 't', 'e', 's', 't', // Domain string
4691 0x00, 0x50, // 16-bit port (80)
4692 };
4693 MockWrite socks5_writes[] = {
4694 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4695 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4696 MockWrite(SYNCHRONOUS,
4697 "GET /socks5 HTTP/1.1\r\n"
4698 "Host: test\r\n"
4699 "Connection: keep-alive\r\n\r\n"),
4700 };
4701 MockRead socks5_reads[] = {
4702 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4703 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4704 MockRead("HTTP/1.0 200 OK\r\n"
4705 "Connection: keep-alive\r\n"
4706 "Content-Length: 15\r\n\r\n"
4707 "SOCKS5 Response"),
4708 };
4709 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4710 socks5_writes, arraysize(socks5_writes));
4711 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4712
4713 MockWrite http_writes[] = {
4714 MockWrite(SYNCHRONOUS,
4715 "GET http://test/http HTTP/1.1\r\n"
4716 "Host: test\r\n"
4717 "Proxy-Connection: keep-alive\r\n\r\n"),
4718 };
4719 MockRead http_reads[] = {
4720 MockRead("HTTP/1.1 200 OK\r\n"
4721 "Proxy-Connection: keep-alive\r\n"
4722 "Content-Length: 13\r\n\r\n"
4723 "HTTP Response"),
4724 };
4725 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4726 http_writes, arraysize(http_writes));
4727 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4728
4729 MockWrite https_writes[] = {
4730 MockWrite(SYNCHRONOUS,
4731 "GET http://test/https HTTP/1.1\r\n"
4732 "Host: test\r\n"
4733 "Proxy-Connection: keep-alive\r\n\r\n"),
4734 };
4735 MockRead https_reads[] = {
4736 MockRead("HTTP/1.1 200 OK\r\n"
4737 "Proxy-Connection: keep-alive\r\n"
4738 "Content-Length: 14\r\n\r\n"
4739 "HTTPS Response"),
4740 };
4741 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4742 https_writes, arraysize(https_writes));
4743 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4744 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4745 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4746
4747 struct TestCase {
4748 GURL url;
4749 std::string expected_response;
4750 // How many idle sockets there should be in the SOCKS proxy socket pool
4751 // after the test.
4752 int expected_idle_socks_sockets;
4753 // How many idle sockets there should be in the HTTP proxy socket pool after
4754 // the test.
4755 int expected_idle_http_sockets;
4756 } const kTestCases[] = {
4757 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4758 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4759 {GURL("http://test/http"), "HTTP Response", 2, 1},
4760 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4761 };
4762
4763 for (const auto& test_case : kTestCases) {
4764 HttpRequestInfo request;
4765 request.method = "GET";
4766 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:104767 request.traffic_annotation =
4768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064769 std::unique_ptr<HttpNetworkTransaction> trans =
4770 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4771 session.get());
4772 TestCompletionCallback callback;
4773 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4774 EXPECT_THAT(callback.GetResult(rv), IsOk());
4775
4776 const HttpResponseInfo* response = trans->GetResponseInfo();
4777 ASSERT_TRUE(response);
4778 ASSERT_TRUE(response->headers);
4779 EXPECT_EQ(200, response->headers->response_code());
4780 std::string response_data;
4781 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4782 EXPECT_EQ(test_case.expected_response, response_data);
4783
4784 // Return the socket to the socket pool, so can make sure it's not used for
4785 // the next requests.
4786 trans.reset();
4787 base::RunLoop().RunUntilIdle();
4788
4789 // Check the number of idle sockets in the pool, to make sure that used
4790 // sockets are indeed being returned to the socket pool. If each request
4791 // doesn't return an idle socket to the pool, the test would incorrectly
4792 // pass.
4793 EXPECT_EQ(
4794 test_case.expected_idle_socks_sockets,
4795 session
4796 ->GetSocketPoolForSOCKSProxy(
4797 HttpNetworkSession::NORMAL_SOCKET_POOL,
4798 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4799 ->IdleSocketCount());
4800 EXPECT_EQ(
4801 test_case.expected_idle_http_sockets,
4802 session
4803 ->GetSocketPoolForHTTPProxy(
4804 HttpNetworkSession::NORMAL_SOCKET_POOL,
4805 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4806 ->IdleSocketCount());
4807 }
4808}
4809
[email protected]029c83b62013-01-24 05:28:204810// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014811TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204812 HttpRequestInfo request1;
4813 request1.method = "GET";
bncce36dca22015-04-21 22:11:234814 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104815 request1.traffic_annotation =
4816 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204817
4818 HttpRequestInfo request2;
4819 request2.method = "GET";
bncce36dca22015-04-21 22:11:234820 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104821 request2.traffic_annotation =
4822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204823
4824 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594825 session_deps_.proxy_resolution_service =
4826 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514827 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074828 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204830
4831 // Since we have proxy, should try to establish tunnel.
4832 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174833 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4834 "Host: www.example.org:443\r\n"
4835 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204836
rsleevidb16bb02015-11-12 23:47:174837 MockWrite("GET /1 HTTP/1.1\r\n"
4838 "Host: www.example.org\r\n"
4839 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204840
rsleevidb16bb02015-11-12 23:47:174841 MockWrite("GET /2 HTTP/1.1\r\n"
4842 "Host: www.example.org\r\n"
4843 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204844 };
4845
4846 // The proxy responds to the connect with a 407, using a persistent
4847 // connection.
4848 MockRead data_reads1[] = {
4849 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4850
4851 MockRead("HTTP/1.1 200 OK\r\n"),
4852 MockRead("Content-Length: 1\r\n\r\n"),
4853 MockRead(SYNCHRONOUS, "1"),
4854
4855 MockRead("HTTP/1.1 200 OK\r\n"),
4856 MockRead("Content-Length: 2\r\n\r\n"),
4857 MockRead(SYNCHRONOUS, "22"),
4858 };
4859
4860 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4861 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074862 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204863 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204865
4866 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584867 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194868 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204869
4870 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204872
4873 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014874 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204875
4876 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524877 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474878 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524879 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204880 EXPECT_EQ(1, response1->headers->GetContentLength());
4881
4882 LoadTimingInfo load_timing_info1;
4883 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4884 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4885
4886 trans1.reset();
4887
4888 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584889 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194890 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204891
4892 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204894
4895 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014896 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204897
4898 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524899 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474900 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524901 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204902 EXPECT_EQ(2, response2->headers->GetContentLength());
4903
4904 LoadTimingInfo load_timing_info2;
4905 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4906 TestLoadTimingReused(load_timing_info2);
4907
4908 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4909
4910 trans2.reset();
4911 session->CloseAllConnections();
4912}
4913
4914// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014915TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204916 HttpRequestInfo request1;
4917 request1.method = "GET";
bncce36dca22015-04-21 22:11:234918 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104919 request1.traffic_annotation =
4920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204921
4922 HttpRequestInfo request2;
4923 request2.method = "GET";
bncce36dca22015-04-21 22:11:234924 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104925 request2.traffic_annotation =
4926 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204927
4928 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594929 session_deps_.proxy_resolution_service =
4930 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514931 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074932 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094933 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204934
4935 // Since we have proxy, should try to establish tunnel.
4936 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174937 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4938 "Host: www.example.org:443\r\n"
4939 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204940
rsleevidb16bb02015-11-12 23:47:174941 MockWrite("GET /1 HTTP/1.1\r\n"
4942 "Host: www.example.org\r\n"
4943 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204944
rsleevidb16bb02015-11-12 23:47:174945 MockWrite("GET /2 HTTP/1.1\r\n"
4946 "Host: www.example.org\r\n"
4947 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204948 };
4949
4950 // The proxy responds to the connect with a 407, using a persistent
4951 // connection.
4952 MockRead data_reads1[] = {
4953 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4954
4955 MockRead("HTTP/1.1 200 OK\r\n"),
4956 MockRead("Content-Length: 1\r\n\r\n"),
4957 MockRead(SYNCHRONOUS, "1"),
4958
4959 MockRead("HTTP/1.1 200 OK\r\n"),
4960 MockRead("Content-Length: 2\r\n\r\n"),
4961 MockRead(SYNCHRONOUS, "22"),
4962 };
4963
4964 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4965 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204967 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204969
4970 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584971 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194972 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204973
4974 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204976
4977 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014978 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204979
4980 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524981 ASSERT_TRUE(response1);
4982 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204983 EXPECT_EQ(1, response1->headers->GetContentLength());
4984
4985 LoadTimingInfo load_timing_info1;
4986 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4987 TestLoadTimingNotReusedWithPac(load_timing_info1,
4988 CONNECT_TIMING_HAS_SSL_TIMES);
4989
4990 trans1.reset();
4991
4992 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584993 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194994 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204995
4996 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204998
4999 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015000 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205001
5002 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525003 ASSERT_TRUE(response2);
5004 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205005 EXPECT_EQ(2, response2->headers->GetContentLength());
5006
5007 LoadTimingInfo load_timing_info2;
5008 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5009 TestLoadTimingReusedWithPac(load_timing_info2);
5010
5011 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5012
5013 trans2.reset();
5014 session->CloseAllConnections();
5015}
5016
[email protected]2df19bb2010-08-25 20:13:465017// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015018TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275019 HttpRequestInfo request;
5020 request.method = "GET";
bncce36dca22015-04-21 22:11:235021 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105022 request.traffic_annotation =
5023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275024
[email protected]2df19bb2010-08-25 20:13:465025 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595026 session_deps_.proxy_resolution_service =
5027 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515028 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075029 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465031
[email protected]2df19bb2010-08-25 20:13:465032 // Since we have proxy, should use full url
5033 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235034 MockWrite(
5035 "GET http://www.example.org/ HTTP/1.1\r\n"
5036 "Host: www.example.org\r\n"
5037 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465038 };
5039
5040 MockRead data_reads1[] = {
5041 MockRead("HTTP/1.1 200 OK\r\n"),
5042 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5043 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065044 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465045 };
5046
5047 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5048 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075049 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065050 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465052
[email protected]49639fa2011-12-20 23:22:415053 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465054
bnc691fda62016-08-12 00:43:165055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505056
bnc691fda62016-08-12 00:43:165057 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465059
5060 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015061 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465062
[email protected]58e32bb2013-01-21 18:23:255063 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165064 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255065 TestLoadTimingNotReused(load_timing_info,
5066 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5067
bnc691fda62016-08-12 00:43:165068 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525069 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465070
tbansal2ecbbc72016-10-06 17:15:475071 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465072 EXPECT_TRUE(response->headers->IsKeepAlive());
5073 EXPECT_EQ(200, response->headers->response_code());
5074 EXPECT_EQ(100, response->headers->GetContentLength());
5075 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5076
5077 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525078 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465079}
5080
[email protected]7642b5ae2010-09-01 20:55:175081// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015082TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275083 HttpRequestInfo request;
5084 request.method = "GET";
bncce36dca22015-04-21 22:11:235085 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105086 request.traffic_annotation =
5087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275088
[email protected]7642b5ae2010-09-01 20:55:175089 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595090 session_deps_.proxy_resolution_service =
5091 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515092 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075093 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175095
bncce36dca22015-04-21 22:11:235096 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:415097 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455098 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415099 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175100
bnc42331402016-07-25 13:36:155101 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:415102 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175103 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415104 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175105 };
5106
rch8e6c6c42015-05-01 14:05:135107 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5108 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075109 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175110
[email protected]8ddf8322012-02-23 18:08:065111 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365112 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175114
[email protected]49639fa2011-12-20 23:22:415115 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175116
bnc691fda62016-08-12 00:43:165117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505118
bnc691fda62016-08-12 00:43:165119 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175121
5122 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015123 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175124
[email protected]58e32bb2013-01-21 18:23:255125 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165126 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255127 TestLoadTimingNotReused(load_timing_info,
5128 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5129
bnc691fda62016-08-12 00:43:165130 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525131 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475132 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525133 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025134 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175135
5136 std::string response_data;
bnc691fda62016-08-12 00:43:165137 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235138 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175139}
5140
[email protected]1c173852014-06-19 12:51:505141// Verifies that a session which races and wins against the owning transaction
5142// (completing prior to host resolution), doesn't fail the transaction.
5143// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015144TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505145 HttpRequestInfo request;
5146 request.method = "GET";
bncce36dca22015-04-21 22:11:235147 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105148 request.traffic_annotation =
5149 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505150
5151 // Configure SPDY proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595152 session_deps_.proxy_resolution_service =
5153 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515154 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505155 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505157
bncce36dca22015-04-21 22:11:235158 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415159 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455160 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415161 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505162
bnc42331402016-07-25 13:36:155163 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415164 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505165 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415166 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505167 };
5168
rch8e6c6c42015-05-01 14:05:135169 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5170 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505171 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5172
5173 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365174 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5176
5177 TestCompletionCallback callback1;
5178
bnc691fda62016-08-12 00:43:165179 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505180
5181 // Stall the hostname resolution begun by the transaction.
5182 session_deps_.host_resolver->set_synchronous_mode(false);
5183 session_deps_.host_resolver->set_ondemand_mode(true);
5184
bnc691fda62016-08-12 00:43:165185 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505187
5188 // Race a session to the proxy, which completes first.
5189 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045190 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5191 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505192 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525193 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505194
5195 // Unstall the resolution begun by the transaction.
5196 session_deps_.host_resolver->set_ondemand_mode(true);
5197 session_deps_.host_resolver->ResolveAllPending();
5198
5199 EXPECT_FALSE(callback1.have_result());
5200 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015201 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505202
bnc691fda62016-08-12 00:43:165203 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525204 ASSERT_TRUE(response);
5205 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025206 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505207
5208 std::string response_data;
bnc691fda62016-08-12 00:43:165209 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505210 EXPECT_EQ(kUploadData, response_data);
5211}
5212
[email protected]dc7bd1c52010-11-12 00:01:135213// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015214TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275215 HttpRequestInfo request;
5216 request.method = "GET";
bncce36dca22015-04-21 22:11:235217 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105218 request.traffic_annotation =
5219 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275220
[email protected]79cb5c12011-09-12 13:12:045221 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595222 session_deps_.proxy_resolution_service =
5223 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515224 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075225 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095226 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135227
[email protected]dc7bd1c52010-11-12 00:01:135228 // The first request will be a bare GET, the second request will be a
5229 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455230 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415231 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:495232 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:385233 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135234 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465235 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135236 };
bncdf80d44fd2016-07-15 20:27:415237 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5238 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
5239 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:135240 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415241 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135242 };
5243
5244 // The first response is a 407 proxy authentication challenge, and the second
5245 // response will be a 200 response since the second request includes a valid
5246 // Authorization header.
5247 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465248 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135249 };
bnc42331402016-07-25 13:36:155250 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235251 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415252 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5253 SpdySerializedFrame body_authentication(
5254 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155255 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415256 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135257 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415258 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465259 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415260 CreateMockRead(resp_data, 4),
5261 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135262 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135263 };
5264
rch8e6c6c42015-05-01 14:05:135265 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5266 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075267 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135268
[email protected]8ddf8322012-02-23 18:08:065269 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365270 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135272
[email protected]49639fa2011-12-20 23:22:415273 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135274
bnc691fda62016-08-12 00:43:165275 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135276
bnc691fda62016-08-12 00:43:165277 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015278 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135279
5280 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015281 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135282
bnc691fda62016-08-12 00:43:165283 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135284
wezca1070932016-05-26 20:30:525285 ASSERT_TRUE(response);
5286 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135287 EXPECT_EQ(407, response->headers->response_code());
5288 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435289 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135290
[email protected]49639fa2011-12-20 23:22:415291 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135292
bnc691fda62016-08-12 00:43:165293 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015294 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135295
5296 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015297 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135298
bnc691fda62016-08-12 00:43:165299 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135300
wezca1070932016-05-26 20:30:525301 ASSERT_TRUE(response_restart);
5302 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135303 EXPECT_EQ(200, response_restart->headers->response_code());
5304 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525305 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135306}
5307
[email protected]d9da5fe2010-10-13 22:37:165308// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015309TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275310 HttpRequestInfo request;
5311 request.method = "GET";
bncce36dca22015-04-21 22:11:235312 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105313 request.traffic_annotation =
5314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275315
[email protected]d9da5fe2010-10-13 22:37:165316 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595317 session_deps_.proxy_resolution_service =
5318 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515319 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075320 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165322
bnc691fda62016-08-12 00:43:165323 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165324
bncce36dca22015-04-21 22:11:235325 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415326 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235327 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5328 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165329
bncce36dca22015-04-21 22:11:235330 const char get[] =
5331 "GET / HTTP/1.1\r\n"
5332 "Host: www.example.org\r\n"
5333 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415334 SpdySerializedFrame wrapped_get(
5335 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:155336 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165337 const char resp[] = "HTTP/1.1 200 OK\r\n"
5338 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415339 SpdySerializedFrame wrapped_get_resp(
5340 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
5341 SpdySerializedFrame wrapped_body(
5342 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
5343 SpdySerializedFrame window_update(
5344 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045345
5346 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415347 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5348 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045349 };
5350
[email protected]d9da5fe2010-10-13 22:37:165351 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415352 CreateMockRead(conn_resp, 1, ASYNC),
5353 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5354 CreateMockRead(wrapped_body, 4, ASYNC),
5355 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135356 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165357 };
5358
rch8e6c6c42015-05-01 14:05:135359 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5360 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075361 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165362
[email protected]8ddf8322012-02-23 18:08:065363 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365364 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065366 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165368
[email protected]49639fa2011-12-20 23:22:415369 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165370
bnc691fda62016-08-12 00:43:165371 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165373
5374 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015375 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165376
[email protected]58e32bb2013-01-21 18:23:255377 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165378 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255379 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5380
bnc691fda62016-08-12 00:43:165381 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525382 ASSERT_TRUE(response);
5383 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165384 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5385
5386 std::string response_data;
bnc691fda62016-08-12 00:43:165387 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165388 EXPECT_EQ("1234567890", response_data);
5389}
5390
5391// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015392TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5393 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385394
[email protected]cb9bf6ca2011-01-28 13:15:275395 HttpRequestInfo request;
5396 request.method = "GET";
bncce36dca22015-04-21 22:11:235397 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105398 request.traffic_annotation =
5399 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275400
[email protected]d9da5fe2010-10-13 22:37:165401 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595402 session_deps_.proxy_resolution_service =
5403 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515404 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075405 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095406 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165407
bnc691fda62016-08-12 00:43:165408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165409
bncce36dca22015-04-21 22:11:235410 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415411 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235412 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5413 // fetch https://www.example.org/ via SPDY
5414 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415415 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495416 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415417 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155418 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415419 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155420 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415421 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025422 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415423 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5424 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025425 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415426 SpdySerializedFrame window_update_get_resp(
5427 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5428 SpdySerializedFrame window_update_body(
5429 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045430
5431 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415432 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5433 CreateMockWrite(window_update_get_resp, 6),
5434 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045435 };
5436
[email protected]d9da5fe2010-10-13 22:37:165437 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415438 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095439 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415440 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5441 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135442 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165443 };
5444
rch32320842015-05-16 15:57:095445 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5446 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075447 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165448
[email protected]8ddf8322012-02-23 18:08:065449 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365450 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075451 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065452 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365453 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165455
[email protected]49639fa2011-12-20 23:22:415456 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165457
bnc691fda62016-08-12 00:43:165458 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165460
rch32320842015-05-16 15:57:095461 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555462 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095463 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595464 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165465 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015466 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165467
[email protected]58e32bb2013-01-21 18:23:255468 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165469 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255470 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5471
bnc691fda62016-08-12 00:43:165472 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525473 ASSERT_TRUE(response);
5474 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025475 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165476
5477 std::string response_data;
bnc691fda62016-08-12 00:43:165478 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235479 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165480}
5481
5482// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015483TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275484 HttpRequestInfo request;
5485 request.method = "GET";
bncce36dca22015-04-21 22:11:235486 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105487 request.traffic_annotation =
5488 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275489
[email protected]d9da5fe2010-10-13 22:37:165490 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595491 session_deps_.proxy_resolution_service =
5492 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515493 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075494 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165496
bnc691fda62016-08-12 00:43:165497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165498
bncce36dca22015-04-21 22:11:235499 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415500 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235501 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415502 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085503 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165504
5505 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415506 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165507 };
5508
bnc42331402016-07-25 13:36:155509 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415510 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165511 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415512 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165513 };
5514
rch8e6c6c42015-05-01 14:05:135515 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5516 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075517 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165518
[email protected]8ddf8322012-02-23 18:08:065519 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365520 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075521 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065522 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365523 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165525
[email protected]49639fa2011-12-20 23:22:415526 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165527
bnc691fda62016-08-12 00:43:165528 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165530
5531 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015532 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165533
ttuttle960fcbf2016-04-19 13:26:325534 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165535}
5536
[email protected]f6c63db52013-02-02 00:35:225537// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5538// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015539TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225540 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5541 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595542 session_deps_.proxy_resolution_service =
5543 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515544 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075545 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095546 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505547 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225548
5549 HttpRequestInfo request1;
5550 request1.method = "GET";
bncce36dca22015-04-21 22:11:235551 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225552 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105553 request1.traffic_annotation =
5554 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225555
5556 HttpRequestInfo request2;
5557 request2.method = "GET";
bncce36dca22015-04-21 22:11:235558 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225559 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105560 request2.traffic_annotation =
5561 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225562
bncce36dca22015-04-21 22:11:235563 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415564 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235565 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155566 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225567
bncce36dca22015-04-21 22:11:235568 // Fetch https://www.example.org/ via HTTP.
5569 const char get1[] =
5570 "GET / HTTP/1.1\r\n"
5571 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225572 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415573 SpdySerializedFrame wrapped_get1(
5574 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225575 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5576 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415577 SpdySerializedFrame wrapped_get_resp1(
5578 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5579 SpdySerializedFrame wrapped_body1(
5580 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5581 SpdySerializedFrame window_update(
5582 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225583
bncce36dca22015-04-21 22:11:235584 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295585 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275586 connect2_block[kHttp2MethodHeader] = "CONNECT";
5587 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155588 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5589 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395590
bnc42331402016-07-25 13:36:155591 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225592
bncce36dca22015-04-21 22:11:235593 // Fetch https://mail.example.org/ via HTTP.
5594 const char get2[] =
5595 "GET / HTTP/1.1\r\n"
5596 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225597 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415598 SpdySerializedFrame wrapped_get2(
5599 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225600 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5601 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415602 SpdySerializedFrame wrapped_get_resp2(
5603 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5604 SpdySerializedFrame wrapped_body2(
5605 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225606
5607 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415608 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5609 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225610 };
5611
5612 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415613 CreateMockRead(conn_resp1, 1, ASYNC),
5614 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5615 CreateMockRead(wrapped_body1, 4, ASYNC),
5616 CreateMockRead(conn_resp2, 6, ASYNC),
5617 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5618 CreateMockRead(wrapped_body2, 9, ASYNC),
5619 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225620 };
5621
mmenke11eb5152015-06-09 14:50:505622 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5623 arraysize(spdy_writes));
5624 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225625
5626 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365627 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225629 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225631 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225633
5634 TestCompletionCallback callback;
5635
bnc691fda62016-08-12 00:43:165636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205637 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015638 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225639
5640 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165641 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225642 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5643
bnc691fda62016-08-12 00:43:165644 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525645 ASSERT_TRUE(response);
5646 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225647 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5648
5649 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295650 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165651 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505652 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225653
bnc691fda62016-08-12 00:43:165654 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205655 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015656 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225657
5658 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165659 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225660 // Even though the SPDY connection is reused, a new tunnelled connection has
5661 // to be created, so the socket's load timing looks like a fresh connection.
5662 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5663
5664 // The requests should have different IDs, since they each are using their own
5665 // separate stream.
5666 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5667
bnc691fda62016-08-12 00:43:165668 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505669 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225670}
5671
5672// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5673// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015674TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225675 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5676 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595677 session_deps_.proxy_resolution_service =
5678 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515679 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075680 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095681 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505682 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225683
5684 HttpRequestInfo request1;
5685 request1.method = "GET";
bncce36dca22015-04-21 22:11:235686 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225687 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105688 request1.traffic_annotation =
5689 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225690
5691 HttpRequestInfo request2;
5692 request2.method = "GET";
bncce36dca22015-04-21 22:11:235693 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225694 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105695 request2.traffic_annotation =
5696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225697
bncce36dca22015-04-21 22:11:235698 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415699 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235700 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155701 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225702
bncce36dca22015-04-21 22:11:235703 // Fetch https://www.example.org/ via HTTP.
5704 const char get1[] =
5705 "GET / HTTP/1.1\r\n"
5706 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225707 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415708 SpdySerializedFrame wrapped_get1(
5709 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225710 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5711 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415712 SpdySerializedFrame wrapped_get_resp1(
5713 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5714 SpdySerializedFrame wrapped_body1(
5715 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5716 SpdySerializedFrame window_update(
5717 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225718
bncce36dca22015-04-21 22:11:235719 // Fetch https://www.example.org/2 via HTTP.
5720 const char get2[] =
5721 "GET /2 HTTP/1.1\r\n"
5722 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225723 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415724 SpdySerializedFrame wrapped_get2(
5725 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225726 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5727 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415728 SpdySerializedFrame wrapped_get_resp2(
5729 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5730 SpdySerializedFrame wrapped_body2(
5731 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225732
5733 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415734 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5735 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225736 };
5737
5738 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415739 CreateMockRead(conn_resp1, 1, ASYNC),
5740 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465741 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415742 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465743 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415744 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225745 };
5746
mmenke11eb5152015-06-09 14:50:505747 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5748 arraysize(spdy_writes));
5749 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225750
5751 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365752 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225754 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225756
5757 TestCompletionCallback callback;
5758
bnc87dcefc2017-05-25 12:47:585759 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195760 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205761 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225763
5764 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015765 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225766
5767 LoadTimingInfo load_timing_info;
5768 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5769 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5770
5771 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525772 ASSERT_TRUE(response);
5773 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225774 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5775
5776 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295777 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505778 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225779 trans.reset();
5780
bnc87dcefc2017-05-25 12:47:585781 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205783 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225785
[email protected]f6c63db52013-02-02 00:35:225786 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015787 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225788
5789 LoadTimingInfo load_timing_info2;
5790 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5791 TestLoadTimingReused(load_timing_info2);
5792
5793 // The requests should have the same ID.
5794 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5795
[email protected]90499482013-06-01 00:39:505796 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225797}
5798
5799// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5800// Proxy to different servers.
bncd16676a2016-07-20 16:23:015801TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225802 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595803 session_deps_.proxy_resolution_service =
5804 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515805 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095807 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505808 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225809
5810 HttpRequestInfo request1;
5811 request1.method = "GET";
bncce36dca22015-04-21 22:11:235812 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225813 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105814 request1.traffic_annotation =
5815 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225816
5817 HttpRequestInfo request2;
5818 request2.method = "GET";
bncce36dca22015-04-21 22:11:235819 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225820 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105821 request2.traffic_annotation =
5822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225823
bncce36dca22015-04-21 22:11:235824 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265825 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235826 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415827 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155828 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5829 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415830 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385831 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225832
bncce36dca22015-04-21 22:11:235833 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265834 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235835 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415836 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155837 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5838 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415839 SpdySerializedFrame body2(
5840 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225841
5842 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415843 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225844 };
5845
5846 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415847 CreateMockRead(get_resp1, 1, ASYNC),
5848 CreateMockRead(body1, 2, ASYNC),
5849 CreateMockRead(get_resp2, 4, ASYNC),
5850 CreateMockRead(body2, 5, ASYNC),
5851 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225852 };
5853
mmenke11eb5152015-06-09 14:50:505854 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5855 arraysize(spdy_writes));
5856 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225857
5858 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365859 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225861
5862 TestCompletionCallback callback;
5863
bnc87dcefc2017-05-25 12:47:585864 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195865 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205866 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015867 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225868
5869 LoadTimingInfo load_timing_info;
5870 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5871 TestLoadTimingNotReused(load_timing_info,
5872 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5873
5874 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525875 ASSERT_TRUE(response);
5876 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025877 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225878
5879 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295880 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505881 rv = trans->Read(buf.get(), 256, callback.callback());
5882 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225883 // Delete the first request, so the second one can reuse the socket.
5884 trans.reset();
5885
bnc691fda62016-08-12 00:43:165886 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205887 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015888 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225889
5890 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165891 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225892 TestLoadTimingReused(load_timing_info2);
5893
5894 // The requests should have the same ID.
5895 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5896
bnc691fda62016-08-12 00:43:165897 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505898 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225899}
5900
[email protected]2df19bb2010-08-25 20:13:465901// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015902TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465903 HttpRequestInfo request;
5904 request.method = "GET";
bncce36dca22015-04-21 22:11:235905 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465906 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295907 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:105908 request.traffic_annotation =
5909 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465910
[email protected]79cb5c12011-09-12 13:12:045911 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595912 session_deps_.proxy_resolution_service =
5913 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515914 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075915 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275917
[email protected]2df19bb2010-08-25 20:13:465918 // Since we have proxy, should use full url
5919 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165920 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5921 "Host: www.example.org\r\n"
5922 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465923
bnc691fda62016-08-12 00:43:165924 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235925 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165926 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5927 "Host: www.example.org\r\n"
5928 "Proxy-Connection: keep-alive\r\n"
5929 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465930 };
5931
5932 // The proxy responds to the GET with a 407, using a persistent
5933 // connection.
5934 MockRead data_reads1[] = {
5935 // No credentials.
5936 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5937 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5938 MockRead("Proxy-Connection: keep-alive\r\n"),
5939 MockRead("Content-Length: 0\r\n\r\n"),
5940
5941 MockRead("HTTP/1.1 200 OK\r\n"),
5942 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5943 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065944 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465945 };
5946
5947 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5948 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075949 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065950 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465952
[email protected]49639fa2011-12-20 23:22:415953 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465954
bnc691fda62016-08-12 00:43:165955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505956
bnc691fda62016-08-12 00:43:165957 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465959
5960 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015961 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465962
[email protected]58e32bb2013-01-21 18:23:255963 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165964 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255965 TestLoadTimingNotReused(load_timing_info,
5966 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5967
bnc691fda62016-08-12 00:43:165968 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525969 ASSERT_TRUE(response);
5970 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465971 EXPECT_EQ(407, response->headers->response_code());
5972 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435973 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465974
[email protected]49639fa2011-12-20 23:22:415975 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465976
bnc691fda62016-08-12 00:43:165977 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465979
5980 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015981 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465982
[email protected]58e32bb2013-01-21 18:23:255983 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165984 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255985 // Retrying with HTTP AUTH is considered to be reusing a socket.
5986 TestLoadTimingReused(load_timing_info);
5987
bnc691fda62016-08-12 00:43:165988 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525989 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465990
5991 EXPECT_TRUE(response->headers->IsKeepAlive());
5992 EXPECT_EQ(200, response->headers->response_code());
5993 EXPECT_EQ(100, response->headers->GetContentLength());
5994 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5995
5996 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525997 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465998}
5999
[email protected]23e482282013-06-14 16:08:026000void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086001 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426002 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086003 request.method = "GET";
bncce36dca22015-04-21 22:11:236004 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106005 request.traffic_annotation =
6006 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086007
[email protected]cb9bf6ca2011-01-28 13:15:276008 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596009 session_deps_.proxy_resolution_service =
6010 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096011 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276012
[email protected]c744cf22009-02-27 07:28:086013 // Since we have proxy, should try to establish tunnel.
6014 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176015 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6016 "Host: www.example.org:443\r\n"
6017 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086018 };
6019
6020 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236021 status, MockRead("Content-Length: 10\r\n\r\n"),
6022 // No response body because the test stops reading here.
6023 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086024 };
6025
[email protected]31a2bfe2010-02-09 08:03:396026 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6027 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076028 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086029
[email protected]49639fa2011-12-20 23:22:416030 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086031
bnc691fda62016-08-12 00:43:166032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506033
tfarina42834112016-09-22 13:38:206034 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086036
6037 rv = callback.WaitForResult();
6038 EXPECT_EQ(expected_status, rv);
6039}
6040
[email protected]23e482282013-06-14 16:08:026041void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236042 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086043 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426044 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086045}
6046
bncd16676a2016-07-20 16:23:016047TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086048 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6049}
6050
bncd16676a2016-07-20 16:23:016051TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086052 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6053}
6054
bncd16676a2016-07-20 16:23:016055TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086056 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6057}
6058
bncd16676a2016-07-20 16:23:016059TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086060 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6061}
6062
bncd16676a2016-07-20 16:23:016063TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086064 ConnectStatusHelper(
6065 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6066}
6067
bncd16676a2016-07-20 16:23:016068TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086069 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6070}
6071
bncd16676a2016-07-20 16:23:016072TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086073 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6074}
6075
bncd16676a2016-07-20 16:23:016076TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086077 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6078}
6079
bncd16676a2016-07-20 16:23:016080TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086081 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6082}
6083
bncd16676a2016-07-20 16:23:016084TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086085 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6086}
6087
bncd16676a2016-07-20 16:23:016088TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086089 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6090}
6091
bncd16676a2016-07-20 16:23:016092TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086093 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6094}
6095
bncd16676a2016-07-20 16:23:016096TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086097 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6098}
6099
bncd16676a2016-07-20 16:23:016100TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086101 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6102}
6103
bncd16676a2016-07-20 16:23:016104TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086105 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6106}
6107
bncd16676a2016-07-20 16:23:016108TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086109 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6110}
6111
bncd16676a2016-07-20 16:23:016112TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376113 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6114}
6115
bncd16676a2016-07-20 16:23:016116TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086117 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6118}
6119
bncd16676a2016-07-20 16:23:016120TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086121 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6122}
6123
bncd16676a2016-07-20 16:23:016124TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086125 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6126}
6127
bncd16676a2016-07-20 16:23:016128TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086129 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6130}
6131
bncd16676a2016-07-20 16:23:016132TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086133 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6134}
6135
bncd16676a2016-07-20 16:23:016136TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086137 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6138}
6139
bncd16676a2016-07-20 16:23:016140TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086141 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6142}
6143
bncd16676a2016-07-20 16:23:016144TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086145 ConnectStatusHelperWithExpectedStatus(
6146 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546147 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086148}
6149
bncd16676a2016-07-20 16:23:016150TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086151 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6152}
6153
bncd16676a2016-07-20 16:23:016154TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086155 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6156}
6157
bncd16676a2016-07-20 16:23:016158TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086159 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6160}
6161
bncd16676a2016-07-20 16:23:016162TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086163 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6164}
6165
bncd16676a2016-07-20 16:23:016166TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086167 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6168}
6169
bncd16676a2016-07-20 16:23:016170TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086171 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6172}
6173
bncd16676a2016-07-20 16:23:016174TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086175 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6176}
6177
bncd16676a2016-07-20 16:23:016178TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086179 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6180}
6181
bncd16676a2016-07-20 16:23:016182TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086183 ConnectStatusHelper(
6184 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6185}
6186
bncd16676a2016-07-20 16:23:016187TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086188 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6189}
6190
bncd16676a2016-07-20 16:23:016191TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086192 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6193}
6194
bncd16676a2016-07-20 16:23:016195TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086196 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6197}
6198
bncd16676a2016-07-20 16:23:016199TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086200 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6201}
6202
bncd16676a2016-07-20 16:23:016203TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086204 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6205}
6206
bncd16676a2016-07-20 16:23:016207TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086208 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6209}
6210
bncd16676a2016-07-20 16:23:016211TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086212 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6213}
6214
[email protected]038e9a32008-10-08 22:40:166215// Test the flow when both the proxy server AND origin server require
6216// authentication. Again, this uses basic auth for both since that is
6217// the simplest to mock.
bncd16676a2016-07-20 16:23:016218TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276219 HttpRequestInfo request;
6220 request.method = "GET";
bncce36dca22015-04-21 22:11:236221 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106222 request.traffic_annotation =
6223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276224
[email protected]038e9a32008-10-08 22:40:166225 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596226 session_deps_.proxy_resolution_service =
6227 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076229
bnc691fda62016-08-12 00:43:166230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166231
[email protected]f9ee6b52008-11-08 06:46:236232 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236233 MockWrite(
6234 "GET http://www.example.org/ HTTP/1.1\r\n"
6235 "Host: www.example.org\r\n"
6236 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236237 };
6238
[email protected]038e9a32008-10-08 22:40:166239 MockRead data_reads1[] = {
6240 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6241 // Give a couple authenticate options (only the middle one is actually
6242 // supported).
[email protected]22927ad2009-09-21 19:56:196243 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166244 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6245 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6246 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6247 // Large content-length -- won't matter, as connection will be reset.
6248 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066249 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166250 };
6251
bnc691fda62016-08-12 00:43:166252 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166253 // request we should be issuing -- the final header line contains the
6254 // proxy's credentials.
6255 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236256 MockWrite(
6257 "GET http://www.example.org/ HTTP/1.1\r\n"
6258 "Host: www.example.org\r\n"
6259 "Proxy-Connection: keep-alive\r\n"
6260 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166261 };
6262
6263 // Now the proxy server lets the request pass through to origin server.
6264 // The origin server responds with a 401.
6265 MockRead data_reads2[] = {
6266 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6267 // Note: We are using the same realm-name as the proxy server. This is
6268 // completely valid, as realms are unique across hosts.
6269 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6270 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6271 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066272 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166273 };
6274
bnc691fda62016-08-12 00:43:166275 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166276 // the credentials for both the proxy and origin server.
6277 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236278 MockWrite(
6279 "GET http://www.example.org/ HTTP/1.1\r\n"
6280 "Host: www.example.org\r\n"
6281 "Proxy-Connection: keep-alive\r\n"
6282 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6283 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166284 };
6285
6286 // Lastly we get the desired content.
6287 MockRead data_reads3[] = {
6288 MockRead("HTTP/1.0 200 OK\r\n"),
6289 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6290 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066291 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166292 };
6293
[email protected]31a2bfe2010-02-09 08:03:396294 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6295 data_writes1, arraysize(data_writes1));
6296 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6297 data_writes2, arraysize(data_writes2));
6298 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6299 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076300 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6301 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6302 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166303
[email protected]49639fa2011-12-20 23:22:416304 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166305
tfarina42834112016-09-22 13:38:206306 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016307 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166308
6309 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016310 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166311
bnc691fda62016-08-12 00:43:166312 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526313 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046314 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166315
[email protected]49639fa2011-12-20 23:22:416316 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166317
bnc691fda62016-08-12 00:43:166318 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166320
6321 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016322 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166323
bnc691fda62016-08-12 00:43:166324 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526325 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046326 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166327
[email protected]49639fa2011-12-20 23:22:416328 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166329
bnc691fda62016-08-12 00:43:166330 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6331 callback3.callback());
robpercival214763f2016-07-01 23:27:016332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166333
6334 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016335 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166336
bnc691fda62016-08-12 00:43:166337 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526338 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166339 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166340}
[email protected]4ddaf2502008-10-23 18:26:196341
[email protected]ea9dc9a2009-09-05 00:43:326342// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6343// can't hook into its internals to cause it to generate predictable NTLM
6344// authorization headers.
6345#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376346// The NTLM authentication unit tests are based on known test data from the
6347// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6348// flow rather than the implementation of the NTLM protocol. See net/ntlm
6349// for the implementation and testing of the protocol.
6350//
6351// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296352
6353// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556354TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426355 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246356 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556357 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106358 request.traffic_annotation =
6359 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546360
6361 // Ensure load is not disrupted by flags which suppress behaviour specific
6362 // to other auth schemes.
6363 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246364
Zentaro Kavanagh6ccee512017-09-28 18:34:096365 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6366 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096367 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276368
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376369 // Generate the NTLM messages based on known test data.
6370 std::string negotiate_msg;
6371 std::string challenge_msg;
6372 std::string authenticate_msg;
6373 base::Base64Encode(
6374 base::StringPiece(
6375 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6376 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6377 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556378 base::Base64Encode(
6379 base::StringPiece(
6380 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6381 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6382 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376383 base::Base64Encode(
6384 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096385 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556386 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6387 arraysize(
6388 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376389 &authenticate_msg);
6390
[email protected]3f918782009-02-28 01:29:246391 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556392 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6393 "Host: server\r\n"
6394 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246395 };
6396
6397 MockRead data_reads1[] = {
6398 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046399 // Negotiate and NTLM are often requested together. However, we only want
6400 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6401 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246402 MockRead("WWW-Authenticate: NTLM\r\n"),
6403 MockRead("Connection: close\r\n"),
6404 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366405 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246406 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246407 };
6408
6409 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166410 // After restarting with a null identity, this is the
6411 // request we should be issuing -- the final header line contains a Type
6412 // 1 message.
6413 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556414 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166415 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376416 "Authorization: NTLM "),
6417 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246418
bnc691fda62016-08-12 00:43:166419 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376420 // (using correct credentials). The second request continues on the
6421 // same connection.
bnc691fda62016-08-12 00:43:166422 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556423 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166424 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376425 "Authorization: NTLM "),
6426 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246427 };
6428
6429 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026430 // The origin server responds with a Type 2 message.
6431 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376432 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6433 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026434 MockRead("Content-Type: text/html\r\n\r\n"),
6435 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246436
Bence Béky1e4ef192017-09-18 19:58:026437 // Lastly we get the desired content.
6438 MockRead("HTTP/1.1 200 OK\r\n"),
6439 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6440 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246441 };
6442
[email protected]31a2bfe2010-02-09 08:03:396443 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6444 data_writes1, arraysize(data_writes1));
6445 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6446 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076447 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6448 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246449
Bence Béky83eb3512017-09-05 12:56:096450 SSLSocketDataProvider ssl1(ASYNC, OK);
6451 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6452 SSLSocketDataProvider ssl2(ASYNC, OK);
6453 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6454
[email protected]49639fa2011-12-20 23:22:416455 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246456
bnc691fda62016-08-12 00:43:166457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506458
tfarina42834112016-09-22 13:38:206459 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246461
6462 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016463 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246464
bnc691fda62016-08-12 00:43:166465 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226466
bnc691fda62016-08-12 00:43:166467 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526468 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046469 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246470
[email protected]49639fa2011-12-20 23:22:416471 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256472
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376473 rv = trans.RestartWithAuth(
6474 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6475 callback2.callback());
robpercival214763f2016-07-01 23:27:016476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256477
6478 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016479 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256480
bnc691fda62016-08-12 00:43:166481 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256482
bnc691fda62016-08-12 00:43:166483 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526484 ASSERT_TRUE(response);
6485 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256486
[email protected]49639fa2011-12-20 23:22:416487 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246488
bnc691fda62016-08-12 00:43:166489 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016490 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246491
[email protected]0757e7702009-03-27 04:00:226492 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016493 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246494
bnc691fda62016-08-12 00:43:166495 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526496 ASSERT_TRUE(response);
6497 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026498 EXPECT_EQ(14, response->headers->GetContentLength());
6499
6500 std::string response_data;
6501 rv = ReadTransaction(&trans, &response_data);
6502 EXPECT_THAT(rv, IsOk());
6503 EXPECT_EQ("Please Login\r\n", response_data);
6504
6505 EXPECT_TRUE(data1.AllReadDataConsumed());
6506 EXPECT_TRUE(data1.AllWriteDataConsumed());
6507 EXPECT_TRUE(data2.AllReadDataConsumed());
6508 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246509}
6510
[email protected]385a4672009-03-11 22:21:296511// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556512TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426513 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296514 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556515 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106516 request.traffic_annotation =
6517 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296518
Zentaro Kavanagh6ccee512017-09-28 18:34:096519 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6520 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276522
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376523 // Generate the NTLM messages based on known test data.
6524 std::string negotiate_msg;
6525 std::string challenge_msg;
6526 std::string authenticate_msg;
6527 base::Base64Encode(
6528 base::StringPiece(
6529 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6530 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6531 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556532 base::Base64Encode(
6533 base::StringPiece(
6534 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6535 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6536 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376537 base::Base64Encode(
6538 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096539 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556540 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6541 arraysize(
6542 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376543 &authenticate_msg);
6544
6545 // The authenticate message when |kWrongPassword| is sent.
6546 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556547 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6548 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6549 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6550 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6551 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6552 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376553
Zentaro Kavanagh1890a3d2018-01-29 19:52:556554 // Sanity check that it's the same length as the correct authenticate message
6555 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376556 ASSERT_EQ(authenticate_msg.length(),
6557 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556558 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376559
[email protected]385a4672009-03-11 22:21:296560 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556561 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6562 "Host: server\r\n"
6563 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296564 };
6565
6566 MockRead data_reads1[] = {
6567 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046568 // Negotiate and NTLM are often requested together. However, we only want
6569 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6570 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296571 MockRead("WWW-Authenticate: NTLM\r\n"),
6572 MockRead("Connection: close\r\n"),
6573 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366574 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296575 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296576 };
6577
6578 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166579 // After restarting with a null identity, this is the
6580 // request we should be issuing -- the final header line contains a Type
6581 // 1 message.
6582 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556583 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166584 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376585 "Authorization: NTLM "),
6586 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296587
bnc691fda62016-08-12 00:43:166588 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376589 // (using incorrect credentials). The second request continues on the
6590 // same connection.
bnc691fda62016-08-12 00:43:166591 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556592 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166593 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376594 "Authorization: NTLM "),
6595 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296596 };
6597
6598 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376599 // The origin server responds with a Type 2 message.
6600 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6601 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6602 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6603 MockRead("Content-Type: text/html\r\n\r\n"),
6604 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296605
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376606 // Wrong password.
6607 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6608 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6609 MockRead("Content-Length: 42\r\n"),
6610 MockRead("Content-Type: text/html\r\n\r\n"),
6611 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296612 };
6613
6614 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166615 // After restarting with a null identity, this is the
6616 // request we should be issuing -- the final header line contains a Type
6617 // 1 message.
6618 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556619 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166620 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376621 "Authorization: NTLM "),
6622 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296623
bnc691fda62016-08-12 00:43:166624 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6625 // (the credentials for the origin server). The second request continues
6626 // on the same connection.
6627 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556628 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166629 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376630 "Authorization: NTLM "),
6631 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296632 };
6633
6634 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026635 // The origin server responds with a Type 2 message.
6636 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376637 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6638 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026639 MockRead("Content-Type: text/html\r\n\r\n"),
6640 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296641
Bence Béky1e4ef192017-09-18 19:58:026642 // Lastly we get the desired content.
6643 MockRead("HTTP/1.1 200 OK\r\n"),
6644 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6645 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296646 };
6647
[email protected]31a2bfe2010-02-09 08:03:396648 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6649 data_writes1, arraysize(data_writes1));
6650 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6651 data_writes2, arraysize(data_writes2));
6652 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6653 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076654 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6655 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6656 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296657
Bence Béky83eb3512017-09-05 12:56:096658 SSLSocketDataProvider ssl1(ASYNC, OK);
6659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6660 SSLSocketDataProvider ssl2(ASYNC, OK);
6661 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6662 SSLSocketDataProvider ssl3(ASYNC, OK);
6663 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6664
[email protected]49639fa2011-12-20 23:22:416665 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296666
bnc691fda62016-08-12 00:43:166667 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506668
tfarina42834112016-09-22 13:38:206669 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296671
6672 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016673 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296674
bnc691fda62016-08-12 00:43:166675 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296676
bnc691fda62016-08-12 00:43:166677 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526678 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046679 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296680
[email protected]49639fa2011-12-20 23:22:416681 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296682
[email protected]0757e7702009-03-27 04:00:226683 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376684 rv = trans.RestartWithAuth(
6685 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6686 callback2.callback());
robpercival214763f2016-07-01 23:27:016687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296688
[email protected]10af5fe72011-01-31 16:17:256689 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016690 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296691
bnc691fda62016-08-12 00:43:166692 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416693 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166694 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256696 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016697 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166698 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226699
bnc691fda62016-08-12 00:43:166700 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526701 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046702 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226703
[email protected]49639fa2011-12-20 23:22:416704 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226705
6706 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376707 rv = trans.RestartWithAuth(
6708 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6709 callback4.callback());
robpercival214763f2016-07-01 23:27:016710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256711
6712 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016713 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256714
bnc691fda62016-08-12 00:43:166715 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256716
[email protected]49639fa2011-12-20 23:22:416717 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256718
6719 // One more roundtrip
bnc691fda62016-08-12 00:43:166720 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226722
6723 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016724 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226725
bnc691fda62016-08-12 00:43:166726 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526727 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026728 EXPECT_EQ(14, response->headers->GetContentLength());
6729
6730 std::string response_data;
6731 rv = ReadTransaction(&trans, &response_data);
6732 EXPECT_THAT(rv, IsOk());
6733 EXPECT_EQ("Please Login\r\n", response_data);
6734
6735 EXPECT_TRUE(data1.AllReadDataConsumed());
6736 EXPECT_TRUE(data1.AllWriteDataConsumed());
6737 EXPECT_TRUE(data2.AllReadDataConsumed());
6738 EXPECT_TRUE(data2.AllWriteDataConsumed());
6739 EXPECT_TRUE(data3.AllReadDataConsumed());
6740 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296741}
Bence Béky83eb3512017-09-05 12:56:096742
Bence Béky3238f2e12017-09-22 22:44:496743// Server requests NTLM authentication, which is not supported over HTTP/2.
6744// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096745TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096746 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6747 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096748
Zentaro Kavanagh1890a3d2018-01-29 19:52:556749 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096750
6751 HttpRequestInfo request;
6752 request.method = "GET";
6753 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:106754 request.traffic_annotation =
6755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096756
6757 // First request without credentials.
6758 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6759 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6760 1, std::move(request_headers0), LOWEST, true));
6761
6762 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276763 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096764 response_headers0["www-authenticate"] = "NTLM";
6765 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6766 1, std::move(response_headers0), true));
6767
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376768 // Stream 1 is closed.
6769 spdy_util_.UpdateWithStreamDestruction(1);
6770
6771 // Generate the NTLM messages based on known test data.
6772 std::string negotiate_msg;
6773 std::string challenge_msg;
6774 std::string authenticate_msg;
6775 base::Base64Encode(
6776 base::StringPiece(
6777 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6778 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6779 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556780 base::Base64Encode(
6781 base::StringPiece(
6782 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6783 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6784 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376785 base::Base64Encode(
6786 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096787 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556788 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6789 arraysize(
6790 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376791 &authenticate_msg);
6792
6793 // Retry with authorization header.
6794 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6795 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6796 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6797 3, std::move(request_headers1), LOWEST, true));
6798
6799 SpdySerializedFrame rst(
6800 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6801
Bence Béky3238f2e12017-09-22 22:44:496802 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6803 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096804
6805 // Retry yet again using HTTP/1.1.
6806 MockWrite writes1[] = {
6807 // After restarting with a null identity, this is the
6808 // request we should be issuing -- the final header line contains a Type
6809 // 1 message.
6810 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556811 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096812 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376813 "Authorization: NTLM "),
6814 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096815
6816 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6817 // (the credentials for the origin server). The second request continues
6818 // on the same connection.
6819 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556820 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096821 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376822 "Authorization: NTLM "),
6823 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096824 };
6825
6826 MockRead reads1[] = {
6827 // The origin server responds with a Type 2 message.
6828 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376829 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6830 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096831 MockRead("Content-Type: text/html\r\n\r\n"),
6832 MockRead("You are not authorized to view this page\r\n"),
6833
6834 // Lastly we get the desired content.
6835 MockRead("HTTP/1.1 200 OK\r\n"),
6836 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026837 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096838 };
6839 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6840 arraysize(writes0));
6841 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6842 arraysize(writes1));
6843 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6844 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6845
6846 SSLSocketDataProvider ssl0(ASYNC, OK);
6847 ssl0.next_proto = kProtoHTTP2;
6848 SSLSocketDataProvider ssl1(ASYNC, OK);
6849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6850 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6851
6852 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6853 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6854
6855 TestCompletionCallback callback1;
6856 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6858
6859 rv = callback1.WaitForResult();
6860 EXPECT_THAT(rv, IsOk());
6861
6862 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6863
6864 const HttpResponseInfo* response = trans.GetResponseInfo();
6865 ASSERT_TRUE(response);
6866 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6867
6868 TestCompletionCallback callback2;
6869
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376870 rv = trans.RestartWithAuth(
6871 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6872 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6874
6875 rv = callback2.WaitForResult();
6876 EXPECT_THAT(rv, IsOk());
6877
6878 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6879
6880 response = trans.GetResponseInfo();
6881 ASSERT_TRUE(response);
6882 EXPECT_FALSE(response->auth_challenge);
6883
6884 TestCompletionCallback callback3;
6885
6886 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6888
6889 rv = callback3.WaitForResult();
6890 EXPECT_THAT(rv, IsOk());
6891
6892 response = trans.GetResponseInfo();
6893 ASSERT_TRUE(response);
6894 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026895 EXPECT_EQ(14, response->headers->GetContentLength());
6896
6897 std::string response_data;
6898 rv = ReadTransaction(&trans, &response_data);
6899 EXPECT_THAT(rv, IsOk());
6900 EXPECT_EQ("Please Login\r\n", response_data);
6901
6902 EXPECT_TRUE(data0.AllReadDataConsumed());
6903 EXPECT_TRUE(data0.AllWriteDataConsumed());
6904 EXPECT_TRUE(data1.AllReadDataConsumed());
6905 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096906}
[email protected]ea9dc9a2009-09-05 00:43:326907#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296908
[email protected]4ddaf2502008-10-23 18:26:196909// Test reading a server response which has only headers, and no body.
6910// After some maximum number of bytes is consumed, the transaction should
6911// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016912TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426913 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196914 request.method = "GET";
bncce36dca22015-04-21 22:11:236915 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106916 request.traffic_annotation =
6917 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196918
danakj1fd259a02016-04-16 03:17:096919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276921
[email protected]b75b7b2f2009-10-06 00:54:536922 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436923 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536924 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196925
6926 MockRead data_reads[] = {
6927 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066928 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196929 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066930 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196931 };
[email protected]31a2bfe2010-02-09 08:03:396932 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076933 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196934
[email protected]49639fa2011-12-20 23:22:416935 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196936
tfarina42834112016-09-22 13:38:206937 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196939
6940 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016941 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196942}
[email protected]f4e426b2008-11-05 00:24:496943
6944// Make sure that we don't try to reuse a TCPClientSocket when failing to
6945// establish tunnel.
6946// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016947TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276948 HttpRequestInfo request;
6949 request.method = "GET";
bncce36dca22015-04-21 22:11:236950 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106951 request.traffic_annotation =
6952 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276953
[email protected]f4e426b2008-11-05 00:24:496954 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596955 session_deps_.proxy_resolution_service =
6956 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016957
danakj1fd259a02016-04-16 03:17:096958 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496959
bnc87dcefc2017-05-25 12:47:586960 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196961 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496962
[email protected]f4e426b2008-11-05 00:24:496963 // Since we have proxy, should try to establish tunnel.
6964 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176965 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6966 "Host: www.example.org:443\r\n"
6967 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496968 };
6969
[email protected]77848d12008-11-14 00:00:226970 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496971 // connection. Usually a proxy would return 501 (not implemented),
6972 // or 200 (tunnel established).
6973 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236974 MockRead("HTTP/1.1 404 Not Found\r\n"),
6975 MockRead("Content-Length: 10\r\n\r\n"),
6976 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496977 };
6978
[email protected]31a2bfe2010-02-09 08:03:396979 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6980 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076981 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496982
[email protected]49639fa2011-12-20 23:22:416983 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496984
tfarina42834112016-09-22 13:38:206985 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496987
6988 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016989 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496990
[email protected]b4404c02009-04-10 16:38:526991 // Empty the current queue. This is necessary because idle sockets are
6992 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556993 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526994
[email protected]f4e426b2008-11-05 00:24:496995 // We now check to make sure the TCPClientSocket was not added back to
6996 // the pool.
[email protected]90499482013-06-01 00:39:506997 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496998 trans.reset();
fdoray92e35a72016-06-10 15:54:556999 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497000 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507001 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497002}
[email protected]372d34a2008-11-05 21:30:517003
[email protected]1b157c02009-04-21 01:55:407004// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017005TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427006 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407007 request.method = "GET";
bncce36dca22015-04-21 22:11:237008 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107009 request.traffic_annotation =
7010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407011
danakj1fd259a02016-04-16 03:17:097012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277013
bnc691fda62016-08-12 00:43:167014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277015
[email protected]1b157c02009-04-21 01:55:407016 MockRead data_reads[] = {
7017 // A part of the response body is received with the response headers.
7018 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7019 // The rest of the response body is received in two parts.
7020 MockRead("lo"),
7021 MockRead(" world"),
7022 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067023 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407024 };
7025
[email protected]31a2bfe2010-02-09 08:03:397026 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077027 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407028
[email protected]49639fa2011-12-20 23:22:417029 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407030
tfarina42834112016-09-22 13:38:207031 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407033
7034 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017035 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407036
bnc691fda62016-08-12 00:43:167037 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527038 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407039
wezca1070932016-05-26 20:30:527040 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407041 std::string status_line = response->headers->GetStatusLine();
7042 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7043
[email protected]90499482013-06-01 00:39:507044 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407045
7046 std::string response_data;
bnc691fda62016-08-12 00:43:167047 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017048 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407049 EXPECT_EQ("hello world", response_data);
7050
7051 // Empty the current queue. This is necessary because idle sockets are
7052 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557053 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407054
7055 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507056 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407057}
7058
[email protected]76a505b2010-08-25 06:23:007059// Make sure that we recycle a SSL socket after reading all of the response
7060// body.
bncd16676a2016-07-20 16:23:017061TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007062 HttpRequestInfo request;
7063 request.method = "GET";
bncce36dca22015-04-21 22:11:237064 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107065 request.traffic_annotation =
7066 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007067
7068 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237069 MockWrite(
7070 "GET / HTTP/1.1\r\n"
7071 "Host: www.example.org\r\n"
7072 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007073 };
7074
7075 MockRead data_reads[] = {
7076 MockRead("HTTP/1.1 200 OK\r\n"),
7077 MockRead("Content-Length: 11\r\n\r\n"),
7078 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067079 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007080 };
7081
[email protected]8ddf8322012-02-23 18:08:067082 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077083 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007084
7085 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7086 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077087 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007088
[email protected]49639fa2011-12-20 23:22:417089 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007090
danakj1fd259a02016-04-16 03:17:097091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167092 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007093
tfarina42834112016-09-22 13:38:207094 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007095
robpercival214763f2016-07-01 23:27:017096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7097 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007098
bnc691fda62016-08-12 00:43:167099 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527100 ASSERT_TRUE(response);
7101 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007102 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7103
[email protected]90499482013-06-01 00:39:507104 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007105
7106 std::string response_data;
bnc691fda62016-08-12 00:43:167107 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017108 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007109 EXPECT_EQ("hello world", response_data);
7110
7111 // Empty the current queue. This is necessary because idle sockets are
7112 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557113 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007114
7115 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507116 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007117}
7118
7119// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7120// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017121TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007122 HttpRequestInfo request;
7123 request.method = "GET";
bncce36dca22015-04-21 22:11:237124 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107125 request.traffic_annotation =
7126 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007127
7128 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237129 MockWrite(
7130 "GET / HTTP/1.1\r\n"
7131 "Host: www.example.org\r\n"
7132 "Connection: keep-alive\r\n\r\n"),
7133 MockWrite(
7134 "GET / HTTP/1.1\r\n"
7135 "Host: www.example.org\r\n"
7136 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007137 };
7138
7139 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427140 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7141 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007142
[email protected]8ddf8322012-02-23 18:08:067143 SSLSocketDataProvider ssl(ASYNC, OK);
7144 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007147
7148 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7149 data_writes, arraysize(data_writes));
7150 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
7151 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077152 session_deps_.socket_factory->AddSocketDataProvider(&data);
7153 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007154
[email protected]49639fa2011-12-20 23:22:417155 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007156
danakj1fd259a02016-04-16 03:17:097157 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587158 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197159 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007160
tfarina42834112016-09-22 13:38:207161 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007162
robpercival214763f2016-07-01 23:27:017163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7164 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007165
7166 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527167 ASSERT_TRUE(response);
7168 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007169 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7170
[email protected]90499482013-06-01 00:39:507171 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007172
7173 std::string response_data;
7174 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017175 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007176 EXPECT_EQ("hello world", response_data);
7177
7178 // Empty the current queue. This is necessary because idle sockets are
7179 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557180 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007181
7182 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507183 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007184
7185 // Now start the second transaction, which should reuse the previous socket.
7186
bnc87dcefc2017-05-25 12:47:587187 trans =
Jeremy Roman0579ed62017-08-29 15:56:197188 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007189
tfarina42834112016-09-22 13:38:207190 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007191
robpercival214763f2016-07-01 23:27:017192 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7193 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007194
7195 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527196 ASSERT_TRUE(response);
7197 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007198 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7199
[email protected]90499482013-06-01 00:39:507200 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007201
7202 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017203 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007204 EXPECT_EQ("hello world", response_data);
7205
7206 // Empty the current queue. This is necessary because idle sockets are
7207 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557208 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007209
7210 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507211 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007212}
7213
maksim.sisov0adf8592016-07-15 06:25:567214// Grab a socket, use it, and put it back into the pool. Then, make
7215// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017216TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567217 HttpRequestInfo request;
7218 request.method = "GET";
7219 request.url = GURL("http://www.example.org/");
7220 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107221 request.traffic_annotation =
7222 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567223
7224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7225
bnc691fda62016-08-12 00:43:167226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567227
7228 MockRead data_reads[] = {
7229 // A part of the response body is received with the response headers.
7230 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7231 // The rest of the response body is received in two parts.
7232 MockRead("lo"), MockRead(" world"),
7233 MockRead("junk"), // Should not be read!!
7234 MockRead(SYNCHRONOUS, OK),
7235 };
7236
7237 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7238 session_deps_.socket_factory->AddSocketDataProvider(&data);
7239
7240 TestCompletionCallback callback;
7241
tfarina42834112016-09-22 13:38:207242 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7244
7245 EXPECT_THAT(callback.GetResult(rv), IsOk());
7246
bnc691fda62016-08-12 00:43:167247 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567248 ASSERT_TRUE(response);
7249 EXPECT_TRUE(response->headers);
7250 std::string status_line = response->headers->GetStatusLine();
7251 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7252
7253 // Make memory critical notification and ensure the transaction still has been
7254 // operating right.
7255 base::MemoryPressureListener::NotifyMemoryPressure(
7256 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7257 base::RunLoop().RunUntilIdle();
7258
7259 // Socket should not be flushed as long as it is not idle.
7260 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7261
7262 std::string response_data;
bnc691fda62016-08-12 00:43:167263 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567264 EXPECT_THAT(rv, IsOk());
7265 EXPECT_EQ("hello world", response_data);
7266
7267 // Empty the current queue. This is necessary because idle sockets are
7268 // added to the connection pool asynchronously with a PostTask.
7269 base::RunLoop().RunUntilIdle();
7270
7271 // We now check to make sure the socket was added back to the pool.
7272 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7273
7274 // Idle sockets should be flushed now.
7275 base::MemoryPressureListener::NotifyMemoryPressure(
7276 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7277 base::RunLoop().RunUntilIdle();
7278
7279 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7280}
7281
yucliu48f235d2018-01-11 00:59:557282// Disable idle socket closing on memory pressure.
7283// Grab a socket, use it, and put it back into the pool. Then, make
7284// low memory notification and ensure the socket pool is NOT flushed.
7285TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7286 HttpRequestInfo request;
7287 request.method = "GET";
7288 request.url = GURL("http://www.example.org/");
7289 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107290 request.traffic_annotation =
7291 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557292
7293 // Disable idle socket closing on memory pressure.
7294 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7296
7297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7298
7299 MockRead data_reads[] = {
7300 // A part of the response body is received with the response headers.
7301 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7302 // The rest of the response body is received in two parts.
7303 MockRead("lo"), MockRead(" world"),
7304 MockRead("junk"), // Should not be read!!
7305 MockRead(SYNCHRONOUS, OK),
7306 };
7307
7308 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7309 session_deps_.socket_factory->AddSocketDataProvider(&data);
7310
7311 TestCompletionCallback callback;
7312
7313 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7314 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7315
7316 EXPECT_THAT(callback.GetResult(rv), IsOk());
7317
7318 const HttpResponseInfo* response = trans.GetResponseInfo();
7319 ASSERT_TRUE(response);
7320 EXPECT_TRUE(response->headers);
7321 std::string status_line = response->headers->GetStatusLine();
7322 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7323
7324 // Make memory critical notification and ensure the transaction still has been
7325 // operating right.
7326 base::MemoryPressureListener::NotifyMemoryPressure(
7327 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7328 base::RunLoop().RunUntilIdle();
7329
7330 // Socket should not be flushed as long as it is not idle.
7331 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7332
7333 std::string response_data;
7334 rv = ReadTransaction(&trans, &response_data);
7335 EXPECT_THAT(rv, IsOk());
7336 EXPECT_EQ("hello world", response_data);
7337
7338 // Empty the current queue. This is necessary because idle sockets are
7339 // added to the connection pool asynchronously with a PostTask.
7340 base::RunLoop().RunUntilIdle();
7341
7342 // We now check to make sure the socket was added back to the pool.
7343 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7344
7345 // Idle sockets should NOT be flushed on moderate memory pressure.
7346 base::MemoryPressureListener::NotifyMemoryPressure(
7347 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7348 base::RunLoop().RunUntilIdle();
7349
7350 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7351
7352 // Idle sockets should NOT be flushed on critical memory pressure.
7353 base::MemoryPressureListener::NotifyMemoryPressure(
7354 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7355 base::RunLoop().RunUntilIdle();
7356
7357 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7358}
7359
maksim.sisov0adf8592016-07-15 06:25:567360// Grab an SSL socket, use it, and put it back into the pool. Then, make
7361// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017362TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567363 HttpRequestInfo request;
7364 request.method = "GET";
7365 request.url = GURL("https://www.example.org/");
7366 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107367 request.traffic_annotation =
7368 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567369
7370 MockWrite data_writes[] = {
7371 MockWrite("GET / HTTP/1.1\r\n"
7372 "Host: www.example.org\r\n"
7373 "Connection: keep-alive\r\n\r\n"),
7374 };
7375
7376 MockRead data_reads[] = {
7377 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7378 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7379
7380 SSLSocketDataProvider ssl(ASYNC, OK);
7381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7382
7383 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7384 arraysize(data_writes));
7385 session_deps_.socket_factory->AddSocketDataProvider(&data);
7386
7387 TestCompletionCallback callback;
7388
7389 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167390 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567391
7392 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207393 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567394
7395 EXPECT_THAT(callback.GetResult(rv), IsOk());
7396
bnc691fda62016-08-12 00:43:167397 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567398 ASSERT_TRUE(response);
7399 ASSERT_TRUE(response->headers);
7400 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7401
7402 // Make memory critical notification and ensure the transaction still has been
7403 // operating right.
7404 base::MemoryPressureListener::NotifyMemoryPressure(
7405 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7406 base::RunLoop().RunUntilIdle();
7407
7408 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7409
7410 std::string response_data;
bnc691fda62016-08-12 00:43:167411 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567412 EXPECT_THAT(rv, IsOk());
7413 EXPECT_EQ("hello world", response_data);
7414
7415 // Empty the current queue. This is necessary because idle sockets are
7416 // added to the connection pool asynchronously with a PostTask.
7417 base::RunLoop().RunUntilIdle();
7418
7419 // We now check to make sure the socket was added back to the pool.
7420 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7421
7422 // Make memory notification once again and ensure idle socket is closed.
7423 base::MemoryPressureListener::NotifyMemoryPressure(
7424 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7425 base::RunLoop().RunUntilIdle();
7426
7427 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7428}
7429
[email protected]b4404c02009-04-10 16:38:527430// Make sure that we recycle a socket after a zero-length response.
7431// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017432TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427433 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527434 request.method = "GET";
bncce36dca22015-04-21 22:11:237435 request.url = GURL(
7436 "http://www.example.org/csi?v=3&s=web&action=&"
7437 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7438 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7439 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:107440 request.traffic_annotation =
7441 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527442
danakj1fd259a02016-04-16 03:17:097443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277444
[email protected]b4404c02009-04-10 16:38:527445 MockRead data_reads[] = {
7446 MockRead("HTTP/1.1 204 No Content\r\n"
7447 "Content-Length: 0\r\n"
7448 "Content-Type: text/html\r\n\r\n"),
7449 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067450 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527451 };
7452
[email protected]31a2bfe2010-02-09 08:03:397453 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077454 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527455
mmenkecc2298e2015-12-07 18:20:187456 // Transaction must be created after the MockReads, so it's destroyed before
7457 // them.
bnc691fda62016-08-12 00:43:167458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187459
[email protected]49639fa2011-12-20 23:22:417460 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527461
tfarina42834112016-09-22 13:38:207462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527464
7465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017466 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527467
bnc691fda62016-08-12 00:43:167468 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527469 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527470
wezca1070932016-05-26 20:30:527471 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527472 std::string status_line = response->headers->GetStatusLine();
7473 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7474
[email protected]90499482013-06-01 00:39:507475 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527476
7477 std::string response_data;
bnc691fda62016-08-12 00:43:167478 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017479 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527480 EXPECT_EQ("", response_data);
7481
7482 // Empty the current queue. This is necessary because idle sockets are
7483 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557484 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527485
7486 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507487 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527488}
7489
bncd16676a2016-07-20 16:23:017490TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097491 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227492 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197493 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227494 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277495
[email protected]1c773ea12009-04-28 19:58:427496 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517497 // Transaction 1: a GET request that succeeds. The socket is recycled
7498 // after use.
7499 request[0].method = "GET";
7500 request[0].url = GURL("http://www.google.com/");
7501 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107502 request[0].traffic_annotation =
7503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517504 // Transaction 2: a POST request. Reuses the socket kept alive from
7505 // transaction 1. The first attempts fails when writing the POST data.
7506 // This causes the transaction to retry with a new socket. The second
7507 // attempt succeeds.
7508 request[1].method = "POST";
7509 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277510 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517511 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107512 request[1].traffic_annotation =
7513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517514
danakj1fd259a02016-04-16 03:17:097515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517516
7517 // The first socket is used for transaction 1 and the first attempt of
7518 // transaction 2.
7519
7520 // The response of transaction 1.
7521 MockRead data_reads1[] = {
7522 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7523 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067524 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517525 };
7526 // The mock write results of transaction 1 and the first attempt of
7527 // transaction 2.
7528 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067529 MockWrite(SYNCHRONOUS, 64), // GET
7530 MockWrite(SYNCHRONOUS, 93), // POST
7531 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517532 };
[email protected]31a2bfe2010-02-09 08:03:397533 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7534 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517535
7536 // The second socket is used for the second attempt of transaction 2.
7537
7538 // The response of transaction 2.
7539 MockRead data_reads2[] = {
7540 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7541 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067542 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517543 };
7544 // The mock write results of the second attempt of transaction 2.
7545 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067546 MockWrite(SYNCHRONOUS, 93), // POST
7547 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517548 };
[email protected]31a2bfe2010-02-09 08:03:397549 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7550 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517551
[email protected]bb88e1d32013-05-03 23:11:077552 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7553 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517554
thestig9d3bb0c2015-01-24 00:49:517555 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517556 "hello world", "welcome"
7557 };
7558
7559 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517561
[email protected]49639fa2011-12-20 23:22:417562 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517563
tfarina42834112016-09-22 13:38:207564 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017565 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517566
7567 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017568 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517569
bnc691fda62016-08-12 00:43:167570 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527571 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517572
wezca1070932016-05-26 20:30:527573 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517574 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7575
7576 std::string response_data;
bnc691fda62016-08-12 00:43:167577 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017578 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517579 EXPECT_EQ(kExpectedResponseData[i], response_data);
7580 }
7581}
[email protected]f9ee6b52008-11-08 06:46:237582
7583// Test the request-challenge-retry sequence for basic auth when there is
7584// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167585// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017586TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427587 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237588 request.method = "GET";
bncce36dca22015-04-21 22:11:237589 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417590 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107591 request.traffic_annotation =
7592 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297593
danakj1fd259a02016-04-16 03:17:097594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277596
[email protected]a97cca42009-08-14 01:00:297597 // The password contains an escaped character -- for this test to pass it
7598 // will need to be unescaped by HttpNetworkTransaction.
7599 EXPECT_EQ("b%40r", request.url.password());
7600
[email protected]f9ee6b52008-11-08 06:46:237601 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237602 MockWrite(
7603 "GET / HTTP/1.1\r\n"
7604 "Host: www.example.org\r\n"
7605 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237606 };
7607
7608 MockRead data_reads1[] = {
7609 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7610 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7611 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067612 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237613 };
7614
[email protected]2262e3a2012-05-22 16:08:167615 // After the challenge above, the transaction will be restarted using the
7616 // identity from the url (foo, b@r) to answer the challenge.
7617 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237618 MockWrite(
7619 "GET / HTTP/1.1\r\n"
7620 "Host: www.example.org\r\n"
7621 "Connection: keep-alive\r\n"
7622 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167623 };
7624
7625 MockRead data_reads2[] = {
7626 MockRead("HTTP/1.0 200 OK\r\n"),
7627 MockRead("Content-Length: 100\r\n\r\n"),
7628 MockRead(SYNCHRONOUS, OK),
7629 };
7630
[email protected]31a2bfe2010-02-09 08:03:397631 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7632 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167633 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7634 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077635 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7636 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237637
[email protected]49639fa2011-12-20 23:22:417638 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207639 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237641 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017642 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167643 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167644
7645 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167646 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167648 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017649 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167650 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227651
bnc691fda62016-08-12 00:43:167652 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527653 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167654
7655 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527656 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167657
7658 EXPECT_EQ(100, response->headers->GetContentLength());
7659
7660 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557661 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167662}
7663
7664// Test the request-challenge-retry sequence for basic auth when there is an
7665// incorrect identity in the URL. The identity from the URL should be used only
7666// once.
bncd16676a2016-07-20 16:23:017667TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167668 HttpRequestInfo request;
7669 request.method = "GET";
7670 // Note: the URL has a username:password in it. The password "baz" is
7671 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237672 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167673
7674 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107675 request.traffic_annotation =
7676 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167677
danakj1fd259a02016-04-16 03:17:097678 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167679 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167680
7681 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237682 MockWrite(
7683 "GET / HTTP/1.1\r\n"
7684 "Host: www.example.org\r\n"
7685 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167686 };
7687
7688 MockRead data_reads1[] = {
7689 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7690 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7691 MockRead("Content-Length: 10\r\n\r\n"),
7692 MockRead(SYNCHRONOUS, ERR_FAILED),
7693 };
7694
7695 // After the challenge above, the transaction will be restarted using the
7696 // identity from the url (foo, baz) to answer the challenge.
7697 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237698 MockWrite(
7699 "GET / HTTP/1.1\r\n"
7700 "Host: www.example.org\r\n"
7701 "Connection: keep-alive\r\n"
7702 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167703 };
7704
7705 MockRead data_reads2[] = {
7706 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7707 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7708 MockRead("Content-Length: 10\r\n\r\n"),
7709 MockRead(SYNCHRONOUS, ERR_FAILED),
7710 };
7711
7712 // After the challenge above, the transaction will be restarted using the
7713 // identity supplied by the user (foo, bar) to answer the challenge.
7714 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237715 MockWrite(
7716 "GET / HTTP/1.1\r\n"
7717 "Host: www.example.org\r\n"
7718 "Connection: keep-alive\r\n"
7719 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167720 };
7721
7722 MockRead data_reads3[] = {
7723 MockRead("HTTP/1.0 200 OK\r\n"),
7724 MockRead("Content-Length: 100\r\n\r\n"),
7725 MockRead(SYNCHRONOUS, OK),
7726 };
7727
7728 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7729 data_writes1, arraysize(data_writes1));
7730 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7731 data_writes2, arraysize(data_writes2));
7732 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7733 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077734 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7735 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7736 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167737
7738 TestCompletionCallback callback1;
7739
tfarina42834112016-09-22 13:38:207740 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167742
7743 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017744 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167745
bnc691fda62016-08-12 00:43:167746 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167747 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167748 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167750 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017751 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167752 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167753
bnc691fda62016-08-12 00:43:167754 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527755 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167756 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7757
7758 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167759 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167761 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017762 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167763 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167764
bnc691fda62016-08-12 00:43:167765 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527766 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167767
7768 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527769 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167770
7771 EXPECT_EQ(100, response->headers->GetContentLength());
7772
[email protected]ea9dc9a2009-09-05 00:43:327773 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557774 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327775}
7776
[email protected]2217aa22013-10-11 03:03:547777
7778// Test the request-challenge-retry sequence for basic auth when there is a
7779// correct identity in the URL, but its use is being suppressed. The identity
7780// from the URL should never be used.
bncd16676a2016-07-20 16:23:017781TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547782 HttpRequestInfo request;
7783 request.method = "GET";
bncce36dca22015-04-21 22:11:237784 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547785 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:107786 request.traffic_annotation =
7787 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547788
danakj1fd259a02016-04-16 03:17:097789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547791
7792 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237793 MockWrite(
7794 "GET / HTTP/1.1\r\n"
7795 "Host: www.example.org\r\n"
7796 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547797 };
7798
7799 MockRead data_reads1[] = {
7800 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7801 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7802 MockRead("Content-Length: 10\r\n\r\n"),
7803 MockRead(SYNCHRONOUS, ERR_FAILED),
7804 };
7805
7806 // After the challenge above, the transaction will be restarted using the
7807 // identity supplied by the user, not the one in the URL, to answer the
7808 // challenge.
7809 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237810 MockWrite(
7811 "GET / HTTP/1.1\r\n"
7812 "Host: www.example.org\r\n"
7813 "Connection: keep-alive\r\n"
7814 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547815 };
7816
7817 MockRead data_reads3[] = {
7818 MockRead("HTTP/1.0 200 OK\r\n"),
7819 MockRead("Content-Length: 100\r\n\r\n"),
7820 MockRead(SYNCHRONOUS, OK),
7821 };
7822
7823 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7824 data_writes1, arraysize(data_writes1));
7825 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7826 data_writes3, arraysize(data_writes3));
7827 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7828 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7829
7830 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207831 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547833 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017834 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167835 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547836
bnc691fda62016-08-12 00:43:167837 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527838 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547839 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7840
7841 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167842 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547844 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017845 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167846 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547847
bnc691fda62016-08-12 00:43:167848 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527849 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547850
7851 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527852 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547853 EXPECT_EQ(100, response->headers->GetContentLength());
7854
7855 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557856 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547857}
7858
[email protected]f9ee6b52008-11-08 06:46:237859// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017860TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237862
7863 // Transaction 1: authenticate (foo, bar) on MyRealm1
7864 {
[email protected]1c773ea12009-04-28 19:58:427865 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237866 request.method = "GET";
bncce36dca22015-04-21 22:11:237867 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:107868 request.traffic_annotation =
7869 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237870
bnc691fda62016-08-12 00:43:167871 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277872
[email protected]f9ee6b52008-11-08 06:46:237873 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237874 MockWrite(
7875 "GET /x/y/z HTTP/1.1\r\n"
7876 "Host: www.example.org\r\n"
7877 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237878 };
7879
7880 MockRead data_reads1[] = {
7881 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7882 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7883 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067884 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237885 };
7886
7887 // Resend with authorization (username=foo, password=bar)
7888 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237889 MockWrite(
7890 "GET /x/y/z HTTP/1.1\r\n"
7891 "Host: www.example.org\r\n"
7892 "Connection: keep-alive\r\n"
7893 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237894 };
7895
7896 // Sever accepts the authorization.
7897 MockRead data_reads2[] = {
7898 MockRead("HTTP/1.0 200 OK\r\n"),
7899 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067900 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237901 };
7902
[email protected]31a2bfe2010-02-09 08:03:397903 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7904 data_writes1, arraysize(data_writes1));
7905 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7906 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077907 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7908 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237909
[email protected]49639fa2011-12-20 23:22:417910 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237911
tfarina42834112016-09-22 13:38:207912 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237914
7915 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017916 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237917
bnc691fda62016-08-12 00:43:167918 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527919 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047920 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237921
[email protected]49639fa2011-12-20 23:22:417922 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237923
bnc691fda62016-08-12 00:43:167924 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7925 callback2.callback());
robpercival214763f2016-07-01 23:27:017926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237927
7928 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017929 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237930
bnc691fda62016-08-12 00:43:167931 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527932 ASSERT_TRUE(response);
7933 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237934 EXPECT_EQ(100, response->headers->GetContentLength());
7935 }
7936
7937 // ------------------------------------------------------------------------
7938
7939 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7940 {
[email protected]1c773ea12009-04-28 19:58:427941 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237942 request.method = "GET";
7943 // Note that Transaction 1 was at /x/y/z, so this is in the same
7944 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237945 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:107946 request.traffic_annotation =
7947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237948
bnc691fda62016-08-12 00:43:167949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277950
[email protected]f9ee6b52008-11-08 06:46:237951 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237952 MockWrite(
7953 "GET /x/y/a/b HTTP/1.1\r\n"
7954 "Host: www.example.org\r\n"
7955 "Connection: keep-alive\r\n"
7956 // Send preemptive authorization for MyRealm1
7957 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237958 };
7959
7960 // The server didn't like the preemptive authorization, and
7961 // challenges us for a different realm (MyRealm2).
7962 MockRead data_reads1[] = {
7963 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7964 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7965 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067966 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237967 };
7968
7969 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7970 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237971 MockWrite(
7972 "GET /x/y/a/b HTTP/1.1\r\n"
7973 "Host: www.example.org\r\n"
7974 "Connection: keep-alive\r\n"
7975 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237976 };
7977
7978 // Sever accepts the authorization.
7979 MockRead data_reads2[] = {
7980 MockRead("HTTP/1.0 200 OK\r\n"),
7981 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067982 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237983 };
7984
[email protected]31a2bfe2010-02-09 08:03:397985 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7986 data_writes1, arraysize(data_writes1));
7987 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7988 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077989 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7990 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237991
[email protected]49639fa2011-12-20 23:22:417992 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237993
tfarina42834112016-09-22 13:38:207994 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237996
7997 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017998 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237999
bnc691fda62016-08-12 00:43:168000 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528001 ASSERT_TRUE(response);
8002 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048003 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438004 EXPECT_EQ("http://www.example.org",
8005 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048006 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198007 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238008
[email protected]49639fa2011-12-20 23:22:418009 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238010
bnc691fda62016-08-12 00:43:168011 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8012 callback2.callback());
robpercival214763f2016-07-01 23:27:018013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238014
8015 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018016 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238017
bnc691fda62016-08-12 00:43:168018 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528019 ASSERT_TRUE(response);
8020 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238021 EXPECT_EQ(100, response->headers->GetContentLength());
8022 }
8023
8024 // ------------------------------------------------------------------------
8025
8026 // Transaction 3: Resend a request in MyRealm's protection space --
8027 // succeed with preemptive authorization.
8028 {
[email protected]1c773ea12009-04-28 19:58:428029 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238030 request.method = "GET";
bncce36dca22015-04-21 22:11:238031 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108032 request.traffic_annotation =
8033 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238034
bnc691fda62016-08-12 00:43:168035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278036
[email protected]f9ee6b52008-11-08 06:46:238037 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238038 MockWrite(
8039 "GET /x/y/z2 HTTP/1.1\r\n"
8040 "Host: www.example.org\r\n"
8041 "Connection: keep-alive\r\n"
8042 // The authorization for MyRealm1 gets sent preemptively
8043 // (since the url is in the same protection space)
8044 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238045 };
8046
8047 // Sever accepts the preemptive authorization
8048 MockRead data_reads1[] = {
8049 MockRead("HTTP/1.0 200 OK\r\n"),
8050 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068051 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238052 };
8053
[email protected]31a2bfe2010-02-09 08:03:398054 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8055 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078056 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238057
[email protected]49639fa2011-12-20 23:22:418058 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238059
tfarina42834112016-09-22 13:38:208060 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238062
8063 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018064 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238065
bnc691fda62016-08-12 00:43:168066 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528067 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238068
wezca1070932016-05-26 20:30:528069 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238070 EXPECT_EQ(100, response->headers->GetContentLength());
8071 }
8072
8073 // ------------------------------------------------------------------------
8074
8075 // Transaction 4: request another URL in MyRealm (however the
8076 // url is not known to belong to the protection space, so no pre-auth).
8077 {
[email protected]1c773ea12009-04-28 19:58:428078 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238079 request.method = "GET";
bncce36dca22015-04-21 22:11:238080 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108081 request.traffic_annotation =
8082 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238083
bnc691fda62016-08-12 00:43:168084 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278085
[email protected]f9ee6b52008-11-08 06:46:238086 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238087 MockWrite(
8088 "GET /x/1 HTTP/1.1\r\n"
8089 "Host: www.example.org\r\n"
8090 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238091 };
8092
8093 MockRead data_reads1[] = {
8094 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8095 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8096 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068097 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238098 };
8099
8100 // Resend with authorization from MyRealm's cache.
8101 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238102 MockWrite(
8103 "GET /x/1 HTTP/1.1\r\n"
8104 "Host: www.example.org\r\n"
8105 "Connection: keep-alive\r\n"
8106 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238107 };
8108
8109 // Sever accepts the authorization.
8110 MockRead data_reads2[] = {
8111 MockRead("HTTP/1.0 200 OK\r\n"),
8112 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068113 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238114 };
8115
[email protected]31a2bfe2010-02-09 08:03:398116 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8117 data_writes1, arraysize(data_writes1));
8118 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8119 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078120 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8121 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238122
[email protected]49639fa2011-12-20 23:22:418123 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238124
tfarina42834112016-09-22 13:38:208125 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018126 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238127
8128 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018129 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238130
bnc691fda62016-08-12 00:43:168131 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418132 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168133 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228135 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018136 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168137 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228138
bnc691fda62016-08-12 00:43:168139 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528140 ASSERT_TRUE(response);
8141 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238142 EXPECT_EQ(100, response->headers->GetContentLength());
8143 }
8144
8145 // ------------------------------------------------------------------------
8146
8147 // Transaction 5: request a URL in MyRealm, but the server rejects the
8148 // cached identity. Should invalidate and re-prompt.
8149 {
[email protected]1c773ea12009-04-28 19:58:428150 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238151 request.method = "GET";
bncce36dca22015-04-21 22:11:238152 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:108153 request.traffic_annotation =
8154 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238155
bnc691fda62016-08-12 00:43:168156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278157
[email protected]f9ee6b52008-11-08 06:46:238158 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238159 MockWrite(
8160 "GET /p/q/t HTTP/1.1\r\n"
8161 "Host: www.example.org\r\n"
8162 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238163 };
8164
8165 MockRead data_reads1[] = {
8166 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8167 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8168 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068169 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238170 };
8171
8172 // Resend with authorization from cache for MyRealm.
8173 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238174 MockWrite(
8175 "GET /p/q/t HTTP/1.1\r\n"
8176 "Host: www.example.org\r\n"
8177 "Connection: keep-alive\r\n"
8178 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238179 };
8180
8181 // Sever rejects the authorization.
8182 MockRead data_reads2[] = {
8183 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8184 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8185 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068186 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238187 };
8188
8189 // At this point we should prompt for new credentials for MyRealm.
8190 // Restart with username=foo3, password=foo4.
8191 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238192 MockWrite(
8193 "GET /p/q/t HTTP/1.1\r\n"
8194 "Host: www.example.org\r\n"
8195 "Connection: keep-alive\r\n"
8196 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238197 };
8198
8199 // Sever accepts the authorization.
8200 MockRead data_reads3[] = {
8201 MockRead("HTTP/1.0 200 OK\r\n"),
8202 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068203 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238204 };
8205
[email protected]31a2bfe2010-02-09 08:03:398206 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8207 data_writes1, arraysize(data_writes1));
8208 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8209 data_writes2, arraysize(data_writes2));
8210 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8211 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078212 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8213 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8214 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238215
[email protected]49639fa2011-12-20 23:22:418216 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238217
tfarina42834112016-09-22 13:38:208218 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238220
8221 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018222 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238223
bnc691fda62016-08-12 00:43:168224 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418225 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168226 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228228 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018229 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168230 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228231
bnc691fda62016-08-12 00:43:168232 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528233 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048234 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238235
[email protected]49639fa2011-12-20 23:22:418236 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238237
bnc691fda62016-08-12 00:43:168238 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8239 callback3.callback());
robpercival214763f2016-07-01 23:27:018240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238241
[email protected]0757e7702009-03-27 04:00:228242 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018243 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238244
bnc691fda62016-08-12 00:43:168245 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528246 ASSERT_TRUE(response);
8247 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238248 EXPECT_EQ(100, response->headers->GetContentLength());
8249 }
8250}
[email protected]89ceba9a2009-03-21 03:46:068251
[email protected]3c32c5f2010-05-18 15:18:128252// Tests that nonce count increments when multiple auth attempts
8253// are started with the same nonce.
bncd16676a2016-07-20 16:23:018254TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448255 HttpAuthHandlerDigest::Factory* digest_factory =
8256 new HttpAuthHandlerDigest::Factory();
8257 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8258 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8259 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078260 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098261 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128262
8263 // Transaction 1: authenticate (foo, bar) on MyRealm1
8264 {
[email protected]3c32c5f2010-05-18 15:18:128265 HttpRequestInfo request;
8266 request.method = "GET";
bncce36dca22015-04-21 22:11:238267 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108268 request.traffic_annotation =
8269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128270
bnc691fda62016-08-12 00:43:168271 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278272
[email protected]3c32c5f2010-05-18 15:18:128273 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238274 MockWrite(
8275 "GET /x/y/z HTTP/1.1\r\n"
8276 "Host: www.example.org\r\n"
8277 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128278 };
8279
8280 MockRead data_reads1[] = {
8281 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8282 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8283 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068284 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128285 };
8286
8287 // Resend with authorization (username=foo, password=bar)
8288 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238289 MockWrite(
8290 "GET /x/y/z HTTP/1.1\r\n"
8291 "Host: www.example.org\r\n"
8292 "Connection: keep-alive\r\n"
8293 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8294 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8295 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8296 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128297 };
8298
8299 // Sever accepts the authorization.
8300 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088301 MockRead("HTTP/1.0 200 OK\r\n"),
8302 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128303 };
8304
8305 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8306 data_writes1, arraysize(data_writes1));
8307 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8308 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8310 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128311
[email protected]49639fa2011-12-20 23:22:418312 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128313
tfarina42834112016-09-22 13:38:208314 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128316
8317 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018318 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128319
bnc691fda62016-08-12 00:43:168320 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528321 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048322 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128323
[email protected]49639fa2011-12-20 23:22:418324 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128325
bnc691fda62016-08-12 00:43:168326 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8327 callback2.callback());
robpercival214763f2016-07-01 23:27:018328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128329
8330 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018331 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128332
bnc691fda62016-08-12 00:43:168333 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528334 ASSERT_TRUE(response);
8335 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128336 }
8337
8338 // ------------------------------------------------------------------------
8339
8340 // Transaction 2: Request another resource in digestive's protection space.
8341 // This will preemptively add an Authorization header which should have an
8342 // "nc" value of 2 (as compared to 1 in the first use.
8343 {
[email protected]3c32c5f2010-05-18 15:18:128344 HttpRequestInfo request;
8345 request.method = "GET";
8346 // Note that Transaction 1 was at /x/y/z, so this is in the same
8347 // protection space as digest.
bncce36dca22015-04-21 22:11:238348 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108349 request.traffic_annotation =
8350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128351
bnc691fda62016-08-12 00:43:168352 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278353
[email protected]3c32c5f2010-05-18 15:18:128354 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238355 MockWrite(
8356 "GET /x/y/a/b HTTP/1.1\r\n"
8357 "Host: www.example.org\r\n"
8358 "Connection: keep-alive\r\n"
8359 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8360 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8361 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8362 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128363 };
8364
8365 // Sever accepts the authorization.
8366 MockRead data_reads1[] = {
8367 MockRead("HTTP/1.0 200 OK\r\n"),
8368 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068369 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128370 };
8371
8372 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8373 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078374 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128375
[email protected]49639fa2011-12-20 23:22:418376 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128377
tfarina42834112016-09-22 13:38:208378 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128380
8381 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018382 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128383
bnc691fda62016-08-12 00:43:168384 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528385 ASSERT_TRUE(response);
8386 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128387 }
8388}
8389
[email protected]89ceba9a2009-03-21 03:46:068390// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018391TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068392 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068395
8396 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168397 trans.read_buf_ = new IOBuffer(15);
8398 trans.read_buf_len_ = 15;
8399 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068400
8401 // Setup state in response_
bnc691fda62016-08-12 00:43:168402 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578403 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088404 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578405 response->response_time = base::Time::Now();
8406 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068407
8408 { // Setup state for response_.vary_data
8409 HttpRequestInfo request;
8410 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8411 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278412 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438413 request.extra_headers.SetHeader("Foo", "1");
8414 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508415 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068416 }
8417
8418 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168419 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068420
8421 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168422 EXPECT_FALSE(trans.read_buf_);
8423 EXPECT_EQ(0, trans.read_buf_len_);
8424 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528425 EXPECT_FALSE(response->auth_challenge);
8426 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048427 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088428 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578429 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068430}
8431
[email protected]bacff652009-03-31 17:50:338432// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018433TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338434 HttpRequestInfo request;
8435 request.method = "GET";
bncce36dca22015-04-21 22:11:238436 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108437 request.traffic_annotation =
8438 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338439
danakj1fd259a02016-04-16 03:17:098440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278442
[email protected]bacff652009-03-31 17:50:338443 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238444 MockWrite(
8445 "GET / HTTP/1.1\r\n"
8446 "Host: www.example.org\r\n"
8447 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338448 };
8449
8450 MockRead data_reads[] = {
8451 MockRead("HTTP/1.0 200 OK\r\n"),
8452 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8453 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068454 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338455 };
8456
[email protected]5ecc992a42009-11-11 01:41:598457 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398458 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8459 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068460 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8461 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338462
[email protected]bb88e1d32013-05-03 23:11:078463 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8464 session_deps_.socket_factory->AddSocketDataProvider(&data);
8465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338467
[email protected]49639fa2011-12-20 23:22:418468 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338469
tfarina42834112016-09-22 13:38:208470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338472
8473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018474 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338475
bnc691fda62016-08-12 00:43:168476 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338478
8479 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018480 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338481
bnc691fda62016-08-12 00:43:168482 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338483
wezca1070932016-05-26 20:30:528484 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338485 EXPECT_EQ(100, response->headers->GetContentLength());
8486}
8487
8488// Test HTTPS connections to a site with a bad certificate, going through a
8489// proxy
bncd16676a2016-07-20 16:23:018490TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598491 session_deps_.proxy_resolution_service =
8492 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:338493
8494 HttpRequestInfo request;
8495 request.method = "GET";
bncce36dca22015-04-21 22:11:238496 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108497 request.traffic_annotation =
8498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338499
8500 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178501 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8502 "Host: www.example.org:443\r\n"
8503 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338504 };
8505
8506 MockRead proxy_reads[] = {
8507 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068508 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338509 };
8510
8511 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178512 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8513 "Host: www.example.org:443\r\n"
8514 "Proxy-Connection: keep-alive\r\n\r\n"),
8515 MockWrite("GET / HTTP/1.1\r\n"
8516 "Host: www.example.org\r\n"
8517 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338518 };
8519
8520 MockRead data_reads[] = {
8521 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8522 MockRead("HTTP/1.0 200 OK\r\n"),
8523 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8524 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068525 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338526 };
8527
[email protected]31a2bfe2010-02-09 08:03:398528 StaticSocketDataProvider ssl_bad_certificate(
8529 proxy_reads, arraysize(proxy_reads),
8530 proxy_writes, arraysize(proxy_writes));
8531 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8532 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068533 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8534 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338535
[email protected]bb88e1d32013-05-03 23:11:078536 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8537 session_deps_.socket_factory->AddSocketDataProvider(&data);
8538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8539 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338540
[email protected]49639fa2011-12-20 23:22:418541 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338542
8543 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078544 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338545
danakj1fd259a02016-04-16 03:17:098546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338548
tfarina42834112016-09-22 13:38:208549 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338551
8552 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018553 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338554
bnc691fda62016-08-12 00:43:168555 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338557
8558 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018559 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338560
bnc691fda62016-08-12 00:43:168561 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338562
wezca1070932016-05-26 20:30:528563 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338564 EXPECT_EQ(100, response->headers->GetContentLength());
8565 }
8566}
8567
[email protected]2df19bb2010-08-25 20:13:468568
8569// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018570TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598571 session_deps_.proxy_resolution_service =
8572 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518573 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078574 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468575
8576 HttpRequestInfo request;
8577 request.method = "GET";
bncce36dca22015-04-21 22:11:238578 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108579 request.traffic_annotation =
8580 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468581
8582 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178583 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8584 "Host: www.example.org:443\r\n"
8585 "Proxy-Connection: keep-alive\r\n\r\n"),
8586 MockWrite("GET / HTTP/1.1\r\n"
8587 "Host: www.example.org\r\n"
8588 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468589 };
8590
8591 MockRead data_reads[] = {
8592 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8593 MockRead("HTTP/1.1 200 OK\r\n"),
8594 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8595 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068596 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468597 };
8598
8599 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8600 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068601 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8602 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468603
[email protected]bb88e1d32013-05-03 23:11:078604 session_deps_.socket_factory->AddSocketDataProvider(&data);
8605 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8606 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468607
[email protected]49639fa2011-12-20 23:22:418608 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468609
danakj1fd259a02016-04-16 03:17:098610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468612
tfarina42834112016-09-22 13:38:208613 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018614 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468615
8616 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018617 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168618 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468619
wezca1070932016-05-26 20:30:528620 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468621
tbansal2ecbbc72016-10-06 17:15:478622 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468623 EXPECT_TRUE(response->headers->IsKeepAlive());
8624 EXPECT_EQ(200, response->headers->response_code());
8625 EXPECT_EQ(100, response->headers->GetContentLength());
8626 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208627
8628 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168629 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208630 TestLoadTimingNotReusedWithPac(load_timing_info,
8631 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468632}
8633
[email protected]511f6f52010-12-17 03:58:298634// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018635TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598636 session_deps_.proxy_resolution_service =
8637 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518638 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078639 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298640
8641 HttpRequestInfo request;
8642 request.method = "GET";
bncce36dca22015-04-21 22:11:238643 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108644 request.traffic_annotation =
8645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298646
8647 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178648 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8649 "Host: www.example.org:443\r\n"
8650 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298651 };
8652
8653 MockRead data_reads[] = {
8654 MockRead("HTTP/1.1 302 Redirect\r\n"),
8655 MockRead("Location: http://login.example.com/\r\n"),
8656 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068657 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298658 };
8659
8660 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8661 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068662 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298663
[email protected]bb88e1d32013-05-03 23:11:078664 session_deps_.socket_factory->AddSocketDataProvider(&data);
8665 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298666
[email protected]49639fa2011-12-20 23:22:418667 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298668
danakj1fd259a02016-04-16 03:17:098669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168670 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298671
tfarina42834112016-09-22 13:38:208672 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298674
8675 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018676 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168677 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298678
wezca1070932016-05-26 20:30:528679 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298680
8681 EXPECT_EQ(302, response->headers->response_code());
8682 std::string url;
8683 EXPECT_TRUE(response->headers->IsRedirect(&url));
8684 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208685
8686 // In the case of redirects from proxies, HttpNetworkTransaction returns
8687 // timing for the proxy connection instead of the connection to the host,
8688 // and no send / receive times.
8689 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8690 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168691 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208692
8693 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198694 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208695
8696 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8697 EXPECT_LE(load_timing_info.proxy_resolve_start,
8698 load_timing_info.proxy_resolve_end);
8699 EXPECT_LE(load_timing_info.proxy_resolve_end,
8700 load_timing_info.connect_timing.connect_start);
8701 ExpectConnectTimingHasTimes(
8702 load_timing_info.connect_timing,
8703 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8704
8705 EXPECT_TRUE(load_timing_info.send_start.is_null());
8706 EXPECT_TRUE(load_timing_info.send_end.is_null());
8707 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298708}
8709
8710// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018711TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598712 session_deps_.proxy_resolution_service =
8713 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298714
8715 HttpRequestInfo request;
8716 request.method = "GET";
bncce36dca22015-04-21 22:11:238717 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108718 request.traffic_annotation =
8719 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298720
bncdf80d44fd2016-07-15 20:27:418721 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238722 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418723 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088724 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298725 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418726 CreateMockWrite(conn, 0, SYNCHRONOUS),
8727 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298728 };
8729
8730 static const char* const kExtraHeaders[] = {
8731 "location",
8732 "http://login.example.com/",
8733 };
bnc42331402016-07-25 13:36:158734 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238735 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298736 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418737 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298738 };
8739
rch8e6c6c42015-05-01 14:05:138740 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8741 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068742 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368743 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298744
[email protected]bb88e1d32013-05-03 23:11:078745 session_deps_.socket_factory->AddSocketDataProvider(&data);
8746 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298747
[email protected]49639fa2011-12-20 23:22:418748 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298749
danakj1fd259a02016-04-16 03:17:098750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168751 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298752
tfarina42834112016-09-22 13:38:208753 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018754 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298755
8756 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018757 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168758 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298759
wezca1070932016-05-26 20:30:528760 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298761
8762 EXPECT_EQ(302, response->headers->response_code());
8763 std::string url;
8764 EXPECT_TRUE(response->headers->IsRedirect(&url));
8765 EXPECT_EQ("http://login.example.com/", url);
8766}
8767
[email protected]4eddbc732012-08-09 05:40:178768// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018769TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598770 session_deps_.proxy_resolution_service =
8771 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298772
8773 HttpRequestInfo request;
8774 request.method = "GET";
bncce36dca22015-04-21 22:11:238775 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108776 request.traffic_annotation =
8777 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298778
8779 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178780 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8781 "Host: www.example.org:443\r\n"
8782 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298783 };
8784
8785 MockRead data_reads[] = {
8786 MockRead("HTTP/1.1 404 Not Found\r\n"),
8787 MockRead("Content-Length: 23\r\n\r\n"),
8788 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068789 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298790 };
8791
8792 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8793 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068794 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298795
[email protected]bb88e1d32013-05-03 23:11:078796 session_deps_.socket_factory->AddSocketDataProvider(&data);
8797 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298798
[email protected]49639fa2011-12-20 23:22:418799 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298800
danakj1fd259a02016-04-16 03:17:098801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298803
tfarina42834112016-09-22 13:38:208804 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298806
8807 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018808 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298809
ttuttle960fcbf2016-04-19 13:26:328810 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298811}
8812
[email protected]4eddbc732012-08-09 05:40:178813// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018814TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598815 session_deps_.proxy_resolution_service =
8816 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298817
8818 HttpRequestInfo request;
8819 request.method = "GET";
bncce36dca22015-04-21 22:11:238820 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108821 request.traffic_annotation =
8822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298823
bncdf80d44fd2016-07-15 20:27:418824 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238825 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418826 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088827 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298828 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418829 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298830 };
8831
8832 static const char* const kExtraHeaders[] = {
8833 "location",
8834 "http://login.example.com/",
8835 };
bnc42331402016-07-25 13:36:158836 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238837 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418838 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558839 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298840 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418841 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138842 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298843 };
8844
rch8e6c6c42015-05-01 14:05:138845 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8846 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068847 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368848 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298849
[email protected]bb88e1d32013-05-03 23:11:078850 session_deps_.socket_factory->AddSocketDataProvider(&data);
8851 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298852
[email protected]49639fa2011-12-20 23:22:418853 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298854
danakj1fd259a02016-04-16 03:17:098855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298857
tfarina42834112016-09-22 13:38:208858 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018859 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298860
8861 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018862 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298863
ttuttle960fcbf2016-04-19 13:26:328864 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298865}
8866
[email protected]0c5fb722012-02-28 11:50:358867// Test the request-challenge-retry sequence for basic auth, through
8868// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018869TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358870 HttpRequestInfo request;
8871 request.method = "GET";
bncce36dca22015-04-21 22:11:238872 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358873 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298874 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:108875 request.traffic_annotation =
8876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358877
8878 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598879 session_deps_.proxy_resolution_service =
8880 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518881 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078882 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358884
8885 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418886 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238887 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418888 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088889 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388890 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358891
bnc691fda62016-08-12 00:43:168892 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358893 // be issuing -- the final header line contains the credentials.
8894 const char* const kAuthCredentials[] = {
8895 "proxy-authorization", "Basic Zm9vOmJhcg==",
8896 };
bncdf80d44fd2016-07-15 20:27:418897 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348898 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238899 HostPortPair("www.example.org", 443)));
8900 // fetch https://www.example.org/ via HTTP
8901 const char get[] =
8902 "GET / HTTP/1.1\r\n"
8903 "Host: www.example.org\r\n"
8904 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418905 SpdySerializedFrame wrapped_get(
8906 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358907
8908 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418909 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8910 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358911 };
8912
8913 // The proxy responds to the connect with a 407, using a persistent
8914 // connection.
thestig9d3bb0c2015-01-24 00:49:518915 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358916 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358917 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8918 };
bnc42331402016-07-25 13:36:158919 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418920 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358921
bnc42331402016-07-25 13:36:158922 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358923 const char resp[] = "HTTP/1.1 200 OK\r\n"
8924 "Content-Length: 5\r\n\r\n";
8925
bncdf80d44fd2016-07-15 20:27:418926 SpdySerializedFrame wrapped_get_resp(
8927 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8928 SpdySerializedFrame wrapped_body(
8929 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358930 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418931 CreateMockRead(conn_auth_resp, 1, ASYNC),
8932 CreateMockRead(conn_resp, 4, ASYNC),
8933 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8934 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138935 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358936 };
8937
rch8e6c6c42015-05-01 14:05:138938 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8939 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078940 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358941 // Negotiate SPDY to the proxy
8942 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368943 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078944 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358945 // Vanilla SSL to the server
8946 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078947 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358948
8949 TestCompletionCallback callback1;
8950
bnc87dcefc2017-05-25 12:47:588951 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198952 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358953
8954 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358956
8957 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018958 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468959 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358960 log.GetEntries(&entries);
8961 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008962 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8963 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358964 ExpectLogContainsSomewhere(
8965 entries, pos,
mikecirone8b85c432016-09-08 19:11:008966 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8967 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358968
8969 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528970 ASSERT_TRUE(response);
8971 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358972 EXPECT_EQ(407, response->headers->response_code());
8973 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528974 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438975 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358976
8977 TestCompletionCallback callback2;
8978
8979 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8980 callback2.callback());
robpercival214763f2016-07-01 23:27:018981 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358982
8983 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018984 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358985
8986 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528987 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358988
8989 EXPECT_TRUE(response->headers->IsKeepAlive());
8990 EXPECT_EQ(200, response->headers->response_code());
8991 EXPECT_EQ(5, response->headers->GetContentLength());
8992 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8993
8994 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528995 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358996
[email protected]029c83b62013-01-24 05:28:208997 LoadTimingInfo load_timing_info;
8998 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8999 TestLoadTimingNotReusedWithPac(load_timing_info,
9000 CONNECT_TIMING_HAS_SSL_TIMES);
9001
[email protected]0c5fb722012-02-28 11:50:359002 trans.reset();
9003 session->CloseAllConnections();
9004}
9005
[email protected]7c6f7ba2012-04-03 04:09:299006// Test that an explicitly trusted SPDY proxy can push a resource from an
9007// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019008TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159009 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199010 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159011 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9012 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299013 HttpRequestInfo request;
9014 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109015 request.traffic_annotation =
9016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299017
[email protected]7c6f7ba2012-04-03 04:09:299018 request.method = "GET";
bncce36dca22015-04-21 22:11:239019 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299020 push_request.method = "GET";
9021 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109022 push_request.traffic_annotation =
9023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299024
tbansal28e68f82016-02-04 02:56:159025 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599026 session_deps_.proxy_resolution_service =
9027 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:519028 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079029 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509030
inlinechan894515af2016-12-09 02:40:109031 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509032
danakj1fd259a02016-04-16 03:17:099033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299034
bncdf80d44fd2016-07-15 20:27:419035 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459036 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359037 SpdySerializedFrame stream2_priority(
9038 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299039
9040 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419041 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359042 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299043 };
9044
Bence Béky7bf94362018-01-10 13:19:369045 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
9046 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9047
bncdf80d44fd2016-07-15 20:27:419048 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159049 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299050
bncdf80d44fd2016-07-15 20:27:419051 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299052
[email protected]8a0fc822013-06-27 20:52:439053 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:419054 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
9055 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:299056
9057 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369058 CreateMockRead(stream2_syn, 1, ASYNC),
9059 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359060 CreateMockRead(stream1_body, 4, ASYNC),
9061 CreateMockRead(stream2_body, 5, ASYNC),
9062 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299063 };
9064
rch8e6c6c42015-05-01 14:05:139065 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9066 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079067 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299068 // Negotiate SPDY to the proxy
9069 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369070 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079071 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299072
bnc87dcefc2017-05-25 12:47:589073 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199074 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299075 TestCompletionCallback callback;
9076 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299078
9079 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019080 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299081 const HttpResponseInfo* response = trans->GetResponseInfo();
9082
bnc87dcefc2017-05-25 12:47:589083 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199084 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509085 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299087
9088 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019089 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299090 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9091
wezca1070932016-05-26 20:30:529092 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299093 EXPECT_TRUE(response->headers->IsKeepAlive());
9094
9095 EXPECT_EQ(200, response->headers->response_code());
9096 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9097
9098 std::string response_data;
9099 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019100 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299101 EXPECT_EQ("hello!", response_data);
9102
[email protected]029c83b62013-01-24 05:28:209103 LoadTimingInfo load_timing_info;
9104 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9105 TestLoadTimingNotReusedWithPac(load_timing_info,
9106 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9107
[email protected]7c6f7ba2012-04-03 04:09:299108 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529109 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299110 EXPECT_EQ(200, push_response->headers->response_code());
9111
9112 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299114 EXPECT_EQ("pushed", response_data);
9115
[email protected]029c83b62013-01-24 05:28:209116 LoadTimingInfo push_load_timing_info;
9117 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9118 TestLoadTimingReusedWithPac(push_load_timing_info);
9119 // The transactions should share a socket ID, despite being for different
9120 // origins.
9121 EXPECT_EQ(load_timing_info.socket_log_id,
9122 push_load_timing_info.socket_log_id);
9123
[email protected]7c6f7ba2012-04-03 04:09:299124 trans.reset();
9125 push_trans.reset();
9126 session->CloseAllConnections();
9127}
9128
[email protected]8c843192012-04-05 07:15:009129// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019130TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159131 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199132 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159133 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9134 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009135 HttpRequestInfo request;
9136
9137 request.method = "GET";
bncce36dca22015-04-21 22:11:239138 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109139 request.traffic_annotation =
9140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009141
Lily Houghton8c2f97d2018-01-22 05:06:599142 session_deps_.proxy_resolution_service =
9143 ProxyResolutionService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:519144 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079145 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509146
9147 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109148 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509149
danakj1fd259a02016-04-16 03:17:099150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009151
bncdf80d44fd2016-07-15 20:27:419152 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459153 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009154
bncdf80d44fd2016-07-15 20:27:419155 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:089156 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009157
9158 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419159 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009160 };
9161
bncdf80d44fd2016-07-15 20:27:419162 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159163 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009164
bncdf80d44fd2016-07-15 20:27:419165 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009166
bncdf80d44fd2016-07-15 20:27:419167 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559168 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009169
9170 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419171 CreateMockRead(stream1_reply, 1, ASYNC),
9172 CreateMockRead(stream2_syn, 2, ASYNC),
9173 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599174 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009175 };
9176
rch8e6c6c42015-05-01 14:05:139177 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9178 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079179 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009180 // Negotiate SPDY to the proxy
9181 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369182 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079183 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009184
bnc87dcefc2017-05-25 12:47:589185 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199186 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009187 TestCompletionCallback callback;
9188 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009190
9191 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019192 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009193 const HttpResponseInfo* response = trans->GetResponseInfo();
9194
wezca1070932016-05-26 20:30:529195 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009196 EXPECT_TRUE(response->headers->IsKeepAlive());
9197
9198 EXPECT_EQ(200, response->headers->response_code());
9199 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9200
9201 std::string response_data;
9202 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019203 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009204 EXPECT_EQ("hello!", response_data);
9205
9206 trans.reset();
9207 session->CloseAllConnections();
9208}
9209
tbansal8ef1d3e2016-02-03 04:05:429210// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9211// resources.
bncd16676a2016-07-20 16:23:019212TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159213 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199214 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159215 proxy_delegate->set_trusted_spdy_proxy(
9216 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9217
tbansal8ef1d3e2016-02-03 04:05:429218 HttpRequestInfo request;
9219
9220 request.method = "GET";
9221 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109222 request.traffic_annotation =
9223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429224
9225 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599226 session_deps_.proxy_resolution_service =
9227 ProxyResolutionService::CreateFixed("https://myproxy:70");
tbansal8ef1d3e2016-02-03 04:05:429228 BoundTestNetLog log;
9229 session_deps_.net_log = log.bound().net_log();
9230
9231 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109232 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429233
danakj1fd259a02016-04-16 03:17:099234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429235
bncdf80d44fd2016-07-15 20:27:419236 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459237 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359238 SpdySerializedFrame stream2_priority(
9239 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429240
9241 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419242 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359243 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429244 };
9245
bncdf80d44fd2016-07-15 20:27:419246 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159247 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429248
bncdf80d44fd2016-07-15 20:27:419249 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339250 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499251
bncdf80d44fd2016-07-15 20:27:419252 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429253
bncdf80d44fd2016-07-15 20:27:419254 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159255 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429256
bncdf80d44fd2016-07-15 20:27:419257 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429258
9259 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419260 CreateMockRead(stream1_reply, 1, ASYNC),
9261 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359262 CreateMockRead(stream1_body, 4, ASYNC),
9263 CreateMockRead(stream2_body, 5, ASYNC),
9264 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429265 };
9266
9267 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9268 arraysize(spdy_writes));
9269 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9270 // Negotiate SPDY to the proxy
9271 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369272 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429273 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9274
bnc87dcefc2017-05-25 12:47:589275 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199276 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429277 TestCompletionCallback callback;
9278 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019279 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429280
9281 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019282 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429283 const HttpResponseInfo* response = trans->GetResponseInfo();
9284
wezca1070932016-05-26 20:30:529285 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429286 EXPECT_TRUE(response->headers->IsKeepAlive());
9287
9288 EXPECT_EQ(200, response->headers->response_code());
9289 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9290
9291 std::string response_data;
9292 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019293 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429294 EXPECT_EQ("hello!", response_data);
9295
9296 trans.reset();
9297 session->CloseAllConnections();
9298}
9299
[email protected]2df19bb2010-08-25 20:13:469300// Test HTTPS connections to a site with a bad certificate, going through an
9301// HTTPS proxy
bncd16676a2016-07-20 16:23:019302TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599303 session_deps_.proxy_resolution_service =
9304 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:469305
9306 HttpRequestInfo request;
9307 request.method = "GET";
bncce36dca22015-04-21 22:11:239308 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109309 request.traffic_annotation =
9310 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469311
9312 // Attempt to fetch the URL from a server with a bad cert
9313 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179314 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9315 "Host: www.example.org:443\r\n"
9316 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469317 };
9318
9319 MockRead bad_cert_reads[] = {
9320 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069321 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469322 };
9323
9324 // Attempt to fetch the URL with a good cert
9325 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179326 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9327 "Host: www.example.org:443\r\n"
9328 "Proxy-Connection: keep-alive\r\n\r\n"),
9329 MockWrite("GET / HTTP/1.1\r\n"
9330 "Host: www.example.org\r\n"
9331 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469332 };
9333
9334 MockRead good_cert_reads[] = {
9335 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9336 MockRead("HTTP/1.0 200 OK\r\n"),
9337 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9338 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069339 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469340 };
9341
9342 StaticSocketDataProvider ssl_bad_certificate(
9343 bad_cert_reads, arraysize(bad_cert_reads),
9344 bad_cert_writes, arraysize(bad_cert_writes));
9345 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9346 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069347 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9348 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469349
9350 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9352 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469354
9355 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9357 session_deps_.socket_factory->AddSocketDataProvider(&data);
9358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469359
[email protected]49639fa2011-12-20 23:22:419360 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469361
danakj1fd259a02016-04-16 03:17:099362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469364
tfarina42834112016-09-22 13:38:209365 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469367
9368 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019369 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469370
bnc691fda62016-08-12 00:43:169371 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469373
9374 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019375 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469376
bnc691fda62016-08-12 00:43:169377 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469378
wezca1070932016-05-26 20:30:529379 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469380 EXPECT_EQ(100, response->headers->GetContentLength());
9381}
9382
bncd16676a2016-07-20 16:23:019383TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429384 HttpRequestInfo request;
9385 request.method = "GET";
bncce36dca22015-04-21 22:11:239386 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439387 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9388 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109389 request.traffic_annotation =
9390 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429391
danakj1fd259a02016-04-16 03:17:099392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279394
[email protected]1c773ea12009-04-28 19:58:429395 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239396 MockWrite(
9397 "GET / HTTP/1.1\r\n"
9398 "Host: www.example.org\r\n"
9399 "Connection: keep-alive\r\n"
9400 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429401 };
9402
9403 // Lastly, the server responds with the actual content.
9404 MockRead data_reads[] = {
9405 MockRead("HTTP/1.0 200 OK\r\n"),
9406 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9407 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069408 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429409 };
9410
[email protected]31a2bfe2010-02-09 08:03:399411 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9412 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079413 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429414
[email protected]49639fa2011-12-20 23:22:419415 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429416
tfarina42834112016-09-22 13:38:209417 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429419
9420 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019421 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429422}
9423
bncd16676a2016-07-20 16:23:019424TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299425 HttpRequestInfo request;
9426 request.method = "GET";
bncce36dca22015-04-21 22:11:239427 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299428 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9429 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109430 request.traffic_annotation =
9431 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299432
Lily Houghton8c2f97d2018-01-22 05:06:599433 session_deps_.proxy_resolution_service =
9434 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:099435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279437
[email protected]da81f132010-08-18 23:39:299438 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179439 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9440 "Host: www.example.org:443\r\n"
9441 "Proxy-Connection: keep-alive\r\n"
9442 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299443 };
9444 MockRead data_reads[] = {
9445 // Return an error, so the transaction stops here (this test isn't
9446 // interested in the rest).
9447 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9448 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9449 MockRead("Proxy-Connection: close\r\n\r\n"),
9450 };
9451
9452 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9453 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079454 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299455
[email protected]49639fa2011-12-20 23:22:419456 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299457
tfarina42834112016-09-22 13:38:209458 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299460
9461 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019462 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299463}
9464
bncd16676a2016-07-20 16:23:019465TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429466 HttpRequestInfo request;
9467 request.method = "GET";
bncce36dca22015-04-21 22:11:239468 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169469 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9470 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:109471 request.traffic_annotation =
9472 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429473
danakj1fd259a02016-04-16 03:17:099474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279476
[email protected]1c773ea12009-04-28 19:58:429477 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239478 MockWrite(
9479 "GET / HTTP/1.1\r\n"
9480 "Host: www.example.org\r\n"
9481 "Connection: keep-alive\r\n"
9482 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429483 };
9484
9485 // Lastly, the server responds with the actual content.
9486 MockRead data_reads[] = {
9487 MockRead("HTTP/1.0 200 OK\r\n"),
9488 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9489 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069490 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429491 };
9492
[email protected]31a2bfe2010-02-09 08:03:399493 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9494 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079495 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429496
[email protected]49639fa2011-12-20 23:22:419497 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429498
tfarina42834112016-09-22 13:38:209499 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429501
9502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019503 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429504}
9505
bncd16676a2016-07-20 16:23:019506TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429507 HttpRequestInfo request;
9508 request.method = "POST";
bncce36dca22015-04-21 22:11:239509 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109510 request.traffic_annotation =
9511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429512
danakj1fd259a02016-04-16 03:17:099513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279515
[email protected]1c773ea12009-04-28 19:58:429516 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239517 MockWrite(
9518 "POST / HTTP/1.1\r\n"
9519 "Host: www.example.org\r\n"
9520 "Connection: keep-alive\r\n"
9521 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429522 };
9523
9524 // Lastly, the server responds with the actual content.
9525 MockRead data_reads[] = {
9526 MockRead("HTTP/1.0 200 OK\r\n"),
9527 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9528 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069529 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429530 };
9531
[email protected]31a2bfe2010-02-09 08:03:399532 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9533 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079534 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429535
[email protected]49639fa2011-12-20 23:22:419536 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429537
tfarina42834112016-09-22 13:38:209538 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429540
9541 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019542 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429543}
9544
bncd16676a2016-07-20 16:23:019545TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429546 HttpRequestInfo request;
9547 request.method = "PUT";
bncce36dca22015-04-21 22:11:239548 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109549 request.traffic_annotation =
9550 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429551
danakj1fd259a02016-04-16 03:17:099552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279554
[email protected]1c773ea12009-04-28 19:58:429555 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239556 MockWrite(
9557 "PUT / HTTP/1.1\r\n"
9558 "Host: www.example.org\r\n"
9559 "Connection: keep-alive\r\n"
9560 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429561 };
9562
9563 // Lastly, the server responds with the actual content.
9564 MockRead data_reads[] = {
9565 MockRead("HTTP/1.0 200 OK\r\n"),
9566 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9567 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069568 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429569 };
9570
[email protected]31a2bfe2010-02-09 08:03:399571 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9572 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079573 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429574
[email protected]49639fa2011-12-20 23:22:419575 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429576
tfarina42834112016-09-22 13:38:209577 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019578 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429579
9580 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019581 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429582}
9583
bncd16676a2016-07-20 16:23:019584TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429585 HttpRequestInfo request;
9586 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239587 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109588 request.traffic_annotation =
9589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429590
danakj1fd259a02016-04-16 03:17:099591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279593
[email protected]1c773ea12009-04-28 19:58:429594 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139595 MockWrite("HEAD / HTTP/1.1\r\n"
9596 "Host: www.example.org\r\n"
9597 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429598 };
9599
9600 // Lastly, the server responds with the actual content.
9601 MockRead data_reads[] = {
9602 MockRead("HTTP/1.0 200 OK\r\n"),
9603 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9604 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069605 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429606 };
9607
[email protected]31a2bfe2010-02-09 08:03:399608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9609 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429611
[email protected]49639fa2011-12-20 23:22:419612 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429613
tfarina42834112016-09-22 13:38:209614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429616
9617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019618 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429619}
9620
bncd16676a2016-07-20 16:23:019621TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429622 HttpRequestInfo request;
9623 request.method = "GET";
bncce36dca22015-04-21 22:11:239624 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429625 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109626 request.traffic_annotation =
9627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429628
danakj1fd259a02016-04-16 03:17:099629 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279631
[email protected]1c773ea12009-04-28 19:58:429632 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239633 MockWrite(
9634 "GET / HTTP/1.1\r\n"
9635 "Host: www.example.org\r\n"
9636 "Connection: keep-alive\r\n"
9637 "Pragma: no-cache\r\n"
9638 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429639 };
9640
9641 // Lastly, the server responds with the actual content.
9642 MockRead data_reads[] = {
9643 MockRead("HTTP/1.0 200 OK\r\n"),
9644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9645 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069646 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429647 };
9648
[email protected]31a2bfe2010-02-09 08:03:399649 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9650 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079651 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429652
[email protected]49639fa2011-12-20 23:22:419653 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429654
tfarina42834112016-09-22 13:38:209655 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429657
9658 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019659 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429660}
9661
bncd16676a2016-07-20 16:23:019662TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429663 HttpRequestInfo request;
9664 request.method = "GET";
bncce36dca22015-04-21 22:11:239665 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429666 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109667 request.traffic_annotation =
9668 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429669
danakj1fd259a02016-04-16 03:17:099670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279672
[email protected]1c773ea12009-04-28 19:58:429673 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239674 MockWrite(
9675 "GET / HTTP/1.1\r\n"
9676 "Host: www.example.org\r\n"
9677 "Connection: keep-alive\r\n"
9678 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429679 };
9680
9681 // Lastly, the server responds with the actual content.
9682 MockRead data_reads[] = {
9683 MockRead("HTTP/1.0 200 OK\r\n"),
9684 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9685 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069686 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429687 };
9688
[email protected]31a2bfe2010-02-09 08:03:399689 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9690 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079691 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429692
[email protected]49639fa2011-12-20 23:22:419693 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429694
tfarina42834112016-09-22 13:38:209695 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429697
9698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019699 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429700}
9701
bncd16676a2016-07-20 16:23:019702TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429703 HttpRequestInfo request;
9704 request.method = "GET";
bncce36dca22015-04-21 22:11:239705 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439706 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:109707 request.traffic_annotation =
9708 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429709
danakj1fd259a02016-04-16 03:17:099710 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279712
[email protected]1c773ea12009-04-28 19:58:429713 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239714 MockWrite(
9715 "GET / HTTP/1.1\r\n"
9716 "Host: www.example.org\r\n"
9717 "Connection: keep-alive\r\n"
9718 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429719 };
9720
9721 // Lastly, the server responds with the actual content.
9722 MockRead data_reads[] = {
9723 MockRead("HTTP/1.0 200 OK\r\n"),
9724 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9725 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069726 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429727 };
9728
[email protected]31a2bfe2010-02-09 08:03:399729 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9730 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079731 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429732
[email protected]49639fa2011-12-20 23:22:419733 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429734
tfarina42834112016-09-22 13:38:209735 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429737
9738 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019739 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429740}
9741
bncd16676a2016-07-20 16:23:019742TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479743 HttpRequestInfo request;
9744 request.method = "GET";
bncce36dca22015-04-21 22:11:239745 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439746 request.extra_headers.SetHeader("referer", "www.foo.com");
9747 request.extra_headers.SetHeader("hEllo", "Kitty");
9748 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:109749 request.traffic_annotation =
9750 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479751
danakj1fd259a02016-04-16 03:17:099752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279754
[email protected]270c6412010-03-29 22:02:479755 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239756 MockWrite(
9757 "GET / HTTP/1.1\r\n"
9758 "Host: www.example.org\r\n"
9759 "Connection: keep-alive\r\n"
9760 "referer: www.foo.com\r\n"
9761 "hEllo: Kitty\r\n"
9762 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479763 };
9764
9765 // Lastly, the server responds with the actual content.
9766 MockRead data_reads[] = {
9767 MockRead("HTTP/1.0 200 OK\r\n"),
9768 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9769 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069770 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479771 };
9772
9773 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9774 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079775 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479776
[email protected]49639fa2011-12-20 23:22:419777 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479778
tfarina42834112016-09-22 13:38:209779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479781
9782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019783 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479784}
9785
bncd16676a2016-07-20 16:23:019786TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279787 HttpRequestInfo request;
9788 request.method = "GET";
bncce36dca22015-04-21 22:11:239789 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109790 request.traffic_annotation =
9791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279792
Lily Houghton8c2f97d2018-01-22 05:06:599793 session_deps_.proxy_resolution_service =
9794 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519795 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079796 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029797
danakj1fd259a02016-04-16 03:17:099798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029800
[email protected]3cd17242009-06-23 02:59:029801 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9802 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9803
9804 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239805 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9806 MockWrite(
9807 "GET / HTTP/1.1\r\n"
9808 "Host: www.example.org\r\n"
9809 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029810
9811 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069812 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029813 MockRead("HTTP/1.0 200 OK\r\n"),
9814 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9815 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069816 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029817 };
9818
[email protected]31a2bfe2010-02-09 08:03:399819 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9820 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079821 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029822
[email protected]49639fa2011-12-20 23:22:419823 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029824
tfarina42834112016-09-22 13:38:209825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029827
9828 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019829 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029830
bnc691fda62016-08-12 00:43:169831 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529832 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029833
tbansal2ecbbc72016-10-06 17:15:479834 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209835 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169836 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209837 TestLoadTimingNotReusedWithPac(load_timing_info,
9838 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9839
[email protected]3cd17242009-06-23 02:59:029840 std::string response_text;
bnc691fda62016-08-12 00:43:169841 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019842 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029843 EXPECT_EQ("Payload", response_text);
9844}
9845
bncd16676a2016-07-20 16:23:019846TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279847 HttpRequestInfo request;
9848 request.method = "GET";
bncce36dca22015-04-21 22:11:239849 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109850 request.traffic_annotation =
9851 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279852
Lily Houghton8c2f97d2018-01-22 05:06:599853 session_deps_.proxy_resolution_service =
9854 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519855 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079856 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029857
danakj1fd259a02016-04-16 03:17:099858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029860
[email protected]3cd17242009-06-23 02:59:029861 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9862 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9863
9864 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239865 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9866 arraysize(write_buffer)),
9867 MockWrite(
9868 "GET / HTTP/1.1\r\n"
9869 "Host: www.example.org\r\n"
9870 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029871
9872 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019873 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9874 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359875 MockRead("HTTP/1.0 200 OK\r\n"),
9876 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9877 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069878 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359879 };
9880
[email protected]31a2bfe2010-02-09 08:03:399881 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9882 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079883 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359884
[email protected]8ddf8322012-02-23 18:08:069885 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359887
[email protected]49639fa2011-12-20 23:22:419888 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359889
tfarina42834112016-09-22 13:38:209890 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359892
9893 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019894 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359895
[email protected]029c83b62013-01-24 05:28:209896 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169897 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209898 TestLoadTimingNotReusedWithPac(load_timing_info,
9899 CONNECT_TIMING_HAS_SSL_TIMES);
9900
bnc691fda62016-08-12 00:43:169901 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529902 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479903 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359904
9905 std::string response_text;
bnc691fda62016-08-12 00:43:169906 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019907 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359908 EXPECT_EQ("Payload", response_text);
9909}
9910
bncd16676a2016-07-20 16:23:019911TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209912 HttpRequestInfo request;
9913 request.method = "GET";
bncce36dca22015-04-21 22:11:239914 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109915 request.traffic_annotation =
9916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209917
Lily Houghton8c2f97d2018-01-22 05:06:599918 session_deps_.proxy_resolution_service =
9919 ProxyResolutionService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519920 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079921 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209922
danakj1fd259a02016-04-16 03:17:099923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209925
9926 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9927 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9928
9929 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239930 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9931 MockWrite(
9932 "GET / HTTP/1.1\r\n"
9933 "Host: www.example.org\r\n"
9934 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209935
9936 MockRead data_reads[] = {
9937 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9938 MockRead("HTTP/1.0 200 OK\r\n"),
9939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9940 MockRead("Payload"),
9941 MockRead(SYNCHRONOUS, OK)
9942 };
9943
9944 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9945 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079946 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209947
9948 TestCompletionCallback callback;
9949
tfarina42834112016-09-22 13:38:209950 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209952
9953 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019954 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209955
bnc691fda62016-08-12 00:43:169956 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529957 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209958
9959 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169960 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209961 TestLoadTimingNotReused(load_timing_info,
9962 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9963
9964 std::string response_text;
bnc691fda62016-08-12 00:43:169965 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019966 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209967 EXPECT_EQ("Payload", response_text);
9968}
9969
bncd16676a2016-07-20 16:23:019970TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279971 HttpRequestInfo request;
9972 request.method = "GET";
bncce36dca22015-04-21 22:11:239973 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109974 request.traffic_annotation =
9975 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279976
Lily Houghton8c2f97d2018-01-22 05:06:599977 session_deps_.proxy_resolution_service =
9978 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519979 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079980 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359981
danakj1fd259a02016-04-16 03:17:099982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359984
[email protected]e0c27be2009-07-15 13:09:359985 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9986 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379987 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239988 0x05, // Version
9989 0x01, // Command (CONNECT)
9990 0x00, // Reserved.
9991 0x03, // Address type (DOMAINNAME).
9992 0x0F, // Length of domain (15)
9993 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9994 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379995 };
[email protected]e0c27be2009-07-15 13:09:359996 const char kSOCKS5OkResponse[] =
9997 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9998
9999 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310000 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10001 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10002 MockWrite(
10003 "GET / HTTP/1.1\r\n"
10004 "Host: www.example.org\r\n"
10005 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510006
10007 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110008 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10009 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510010 MockRead("HTTP/1.0 200 OK\r\n"),
10011 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10012 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610013 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510014 };
10015
[email protected]31a2bfe2010-02-09 08:03:3910016 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10017 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710018 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510019
[email protected]49639fa2011-12-20 23:22:4110020 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510021
tfarina42834112016-09-22 13:38:2010022 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510024
10025 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110026 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510027
bnc691fda62016-08-12 00:43:1610028 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210029 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710030 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510031
[email protected]029c83b62013-01-24 05:28:2010032 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610033 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010034 TestLoadTimingNotReusedWithPac(load_timing_info,
10035 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10036
[email protected]e0c27be2009-07-15 13:09:3510037 std::string response_text;
bnc691fda62016-08-12 00:43:1610038 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110039 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510040 EXPECT_EQ("Payload", response_text);
10041}
10042
bncd16676a2016-07-20 16:23:0110043TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710044 HttpRequestInfo request;
10045 request.method = "GET";
bncce36dca22015-04-21 22:11:2310046 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010047 request.traffic_annotation =
10048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710049
Lily Houghton8c2f97d2018-01-22 05:06:5910050 session_deps_.proxy_resolution_service =
10051 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:5110052 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710053 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510054
danakj1fd259a02016-04-16 03:17:0910055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610056 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510057
[email protected]e0c27be2009-07-15 13:09:3510058 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10059 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710060 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310061 0x05, // Version
10062 0x01, // Command (CONNECT)
10063 0x00, // Reserved.
10064 0x03, // Address type (DOMAINNAME).
10065 0x0F, // Length of domain (15)
10066 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10067 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710068 };
10069
[email protected]e0c27be2009-07-15 13:09:3510070 const char kSOCKS5OkResponse[] =
10071 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10072
10073 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310074 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10075 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10076 arraysize(kSOCKS5OkRequest)),
10077 MockWrite(
10078 "GET / HTTP/1.1\r\n"
10079 "Host: www.example.org\r\n"
10080 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510081
10082 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110083 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10084 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210085 MockRead("HTTP/1.0 200 OK\r\n"),
10086 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10087 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610088 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210089 };
10090
[email protected]31a2bfe2010-02-09 08:03:3910091 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10092 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710093 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210094
[email protected]8ddf8322012-02-23 18:08:0610095 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210097
[email protected]49639fa2011-12-20 23:22:4110098 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210099
tfarina42834112016-09-22 13:38:2010100 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210102
10103 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110104 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210105
bnc691fda62016-08-12 00:43:1610106 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210107 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710108 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210109
[email protected]029c83b62013-01-24 05:28:2010110 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610111 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010112 TestLoadTimingNotReusedWithPac(load_timing_info,
10113 CONNECT_TIMING_HAS_SSL_TIMES);
10114
[email protected]3cd17242009-06-23 02:59:0210115 std::string response_text;
bnc691fda62016-08-12 00:43:1610116 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110117 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210118 EXPECT_EQ("Payload", response_text);
10119}
10120
[email protected]448d4ca52012-03-04 04:12:2310121namespace {
10122
[email protected]04e5be32009-06-26 20:00:3110123// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610124
10125struct GroupNameTest {
10126 std::string proxy_server;
10127 std::string url;
10128 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810129 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610130};
10131
danakj1fd259a02016-04-16 03:17:0910132std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710133 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910134 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610135
bnc525e175a2016-06-20 12:36:4010136 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310137 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110138 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210139 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110140 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210141 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610142 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610143
10144 return session;
10145}
10146
mmenkee65e7af2015-10-13 17:16:4210147int GroupNameTransactionHelper(const std::string& url,
10148 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610149 HttpRequestInfo request;
10150 request.method = "GET";
10151 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1010152 request.traffic_annotation =
10153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610154
bnc691fda62016-08-12 00:43:1610155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710156
[email protected]49639fa2011-12-20 23:22:4110157 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610158
10159 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010160 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610161}
10162
[email protected]448d4ca52012-03-04 04:12:2310163} // namespace
10164
bncd16676a2016-07-20 16:23:0110165TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610166 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310167 {
10168 "", // unused
10169 "http://www.example.org/direct",
10170 "www.example.org:80",
10171 false,
10172 },
10173 {
10174 "", // unused
10175 "http://[2001:1418:13:1::25]/direct",
10176 "[2001:1418:13:1::25]:80",
10177 false,
10178 },
[email protected]04e5be32009-06-26 20:00:3110179
bncce36dca22015-04-21 22:11:2310180 // SSL Tests
10181 {
10182 "", // unused
10183 "https://www.example.org/direct_ssl",
10184 "ssl/www.example.org:443",
10185 true,
10186 },
10187 {
10188 "", // unused
10189 "https://[2001:1418:13:1::25]/direct",
10190 "ssl/[2001:1418:13:1::25]:443",
10191 true,
10192 },
10193 {
10194 "", // unused
bncaa60ff402016-06-22 19:12:4210195 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310196 "ssl/host.with.alternate:443",
10197 true,
10198 },
[email protected]2d731a32010-04-29 01:04:0610199 };
[email protected]2ff8b312010-04-26 22:20:5410200
viettrungluue4a8b882014-10-16 06:17:3810201 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910202 session_deps_.proxy_resolution_service =
10203 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910204 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010205 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610206
mmenkee65e7af2015-10-13 17:16:4210207 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810208 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810209 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310210 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810211 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910212 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210213 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10214 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810215 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610216
10217 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210218 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910219 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810220 EXPECT_EQ(tests[i].expected_group_name,
10221 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910222 } else {
[email protected]e60e47a2010-07-14 03:37:1810223 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810224 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910225 }
10226 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10227 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10228 // When SSL proxy is not in use, socket must be requested from
10229 // |transport_conn_pool|.
10230 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610231 }
[email protected]2d731a32010-04-29 01:04:0610232}
10233
bncd16676a2016-07-20 16:23:0110234TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610235 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310236 {
Matt Menked1eb6d42018-01-17 04:54:0610237 "http_proxy", "http://www.example.org/http_proxy_normal",
10238 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310239 },
[email protected]2d731a32010-04-29 01:04:0610240
bncce36dca22015-04-21 22:11:2310241 // SSL Tests
10242 {
Matt Menked1eb6d42018-01-17 04:54:0610243 "http_proxy", "https://www.example.org/http_connect_ssl",
10244 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310245 },
[email protected]af3490e2010-10-16 21:02:2910246
bncce36dca22015-04-21 22:11:2310247 {
Matt Menked1eb6d42018-01-17 04:54:0610248 "http_proxy", "https://host.with.alternate/direct",
10249 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310250 },
[email protected]45499252013-01-23 17:12:5610251
bncce36dca22015-04-21 22:11:2310252 {
Matt Menked1eb6d42018-01-17 04:54:0610253 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10254 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310255 },
[email protected]2d731a32010-04-29 01:04:0610256 };
10257
viettrungluue4a8b882014-10-16 06:17:3810258 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910259 session_deps_.proxy_resolution_service =
10260 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910261 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010262 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610263
mmenkee65e7af2015-10-13 17:16:4210264 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610265
[email protected]e60e47a2010-07-14 03:37:1810266 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310267 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410268 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310269 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410270 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910271 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910272 mock_pool_manager->SetSocketPoolForHTTPProxy(
10273 proxy_host, base::WrapUnique(http_proxy_pool));
10274 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10275 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810276 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610277
10278 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210279 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810280 if (tests[i].ssl)
10281 EXPECT_EQ(tests[i].expected_group_name,
10282 ssl_conn_pool->last_group_name_received());
10283 else
10284 EXPECT_EQ(tests[i].expected_group_name,
10285 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610286 }
[email protected]2d731a32010-04-29 01:04:0610287}
10288
bncd16676a2016-07-20 16:23:0110289TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610290 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310291 {
10292 "socks4://socks_proxy:1080",
10293 "http://www.example.org/socks4_direct",
10294 "socks4/www.example.org:80",
10295 false,
10296 },
10297 {
10298 "socks5://socks_proxy:1080",
10299 "http://www.example.org/socks5_direct",
10300 "socks5/www.example.org:80",
10301 false,
10302 },
[email protected]2d731a32010-04-29 01:04:0610303
bncce36dca22015-04-21 22:11:2310304 // SSL Tests
10305 {
10306 "socks4://socks_proxy:1080",
10307 "https://www.example.org/socks4_ssl",
10308 "socks4/ssl/www.example.org:443",
10309 true,
10310 },
10311 {
10312 "socks5://socks_proxy:1080",
10313 "https://www.example.org/socks5_ssl",
10314 "socks5/ssl/www.example.org:443",
10315 true,
10316 },
[email protected]af3490e2010-10-16 21:02:2910317
bncce36dca22015-04-21 22:11:2310318 {
10319 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210320 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310321 "socks4/ssl/host.with.alternate:443",
10322 true,
10323 },
[email protected]04e5be32009-06-26 20:00:3110324 };
10325
viettrungluue4a8b882014-10-16 06:17:3810326 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910327 session_deps_.proxy_resolution_service =
10328 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910329 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010330 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210331
mmenkee65e7af2015-10-13 17:16:4210332 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110333
[email protected]e60e47a2010-07-14 03:37:1810334 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310335 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410336 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310337 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410338 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910339 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910340 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10341 proxy_host, base::WrapUnique(socks_conn_pool));
10342 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10343 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810344 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110345
bnc691fda62016-08-12 00:43:1610346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110347
[email protected]2d731a32010-04-29 01:04:0610348 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210349 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810350 if (tests[i].ssl)
10351 EXPECT_EQ(tests[i].expected_group_name,
10352 ssl_conn_pool->last_group_name_received());
10353 else
10354 EXPECT_EQ(tests[i].expected_group_name,
10355 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110356 }
10357}
10358
bncd16676a2016-07-20 16:23:0110359TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710360 HttpRequestInfo request;
10361 request.method = "GET";
bncce36dca22015-04-21 22:11:2310362 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010363 request.traffic_annotation =
10364 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710365
Lily Houghton8c2f97d2018-01-22 05:06:5910366 session_deps_.proxy_resolution_service =
10367 ProxyResolutionService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:3210368
[email protected]69719062010-01-05 20:09:2110369 // This simulates failure resolving all hostnames; that means we will fail
10370 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710371 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210372
danakj1fd259a02016-04-16 03:17:0910373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510375
[email protected]49639fa2011-12-20 23:22:4110376 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510377
tfarina42834112016-09-22 13:38:2010378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510380
[email protected]9172a982009-06-06 00:30:2510381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110382 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510383}
10384
[email protected]685af592010-05-11 19:31:2410385// Base test to make sure that when the load flags for a request specify to
10386// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210387void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710388 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710389 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010390 HttpRequestInfo request_info;
10391 request_info.method = "GET";
10392 request_info.load_flags = load_flags;
10393 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010394 request_info.traffic_annotation =
10395 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710396
[email protected]a2c2fb92009-07-18 07:31:0410397 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910398 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210399
danakj1fd259a02016-04-16 03:17:0910400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610401 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810402
bncce36dca22015-04-21 22:11:2310403 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810404 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910405 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010406 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710407 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310408 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010409 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010410 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110413 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810414
10415 // Verify that it was added to host cache, by doing a subsequent async lookup
10416 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010417 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710418 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310419 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010420 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010421 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110422 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810423
bncce36dca22015-04-21 22:11:2310424 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810425 // we can tell if the next lookup hit the cache, or the "network".
10426 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310427 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810428
10429 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10430 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610431 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910432 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710433 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810434
[email protected]3b9cca42009-06-16 01:08:2810435 // Run the request.
tfarina42834112016-09-22 13:38:2010436 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110437 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110438 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810439
10440 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310441 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110442 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810443}
10444
[email protected]685af592010-05-11 19:31:2410445// There are multiple load flags that should trigger the host cache bypass.
10446// Test each in isolation:
bncd16676a2016-07-20 16:23:0110447TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410448 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10449}
10450
bncd16676a2016-07-20 16:23:0110451TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410452 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10453}
10454
bncd16676a2016-07-20 16:23:0110455TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410456 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10457}
10458
[email protected]0877e3d2009-10-17 22:29:5710459// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110460TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710461 HttpRequestInfo request;
10462 request.method = "GET";
10463 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010464 request.traffic_annotation =
10465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710466
10467 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610468 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710469 };
[email protected]31a2bfe2010-02-09 08:03:3910470 StaticSocketDataProvider data(NULL, 0,
10471 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710472 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710474
[email protected]49639fa2011-12-20 23:22:4110475 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710476
bnc691fda62016-08-12 00:43:1610477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710478
tfarina42834112016-09-22 13:38:2010479 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710481
10482 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110483 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910484
10485 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610486 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910487 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710488}
10489
zmo9528c9f42015-08-04 22:12:0810490// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110491TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710492 HttpRequestInfo request;
10493 request.method = "GET";
10494 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010495 request.traffic_annotation =
10496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710497
10498 MockRead data_reads[] = {
10499 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610500 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710501 };
10502
[email protected]31a2bfe2010-02-09 08:03:3910503 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710504 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710506
[email protected]49639fa2011-12-20 23:22:4110507 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710508
bnc691fda62016-08-12 00:43:1610509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710510
tfarina42834112016-09-22 13:38:2010511 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710513
10514 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110515 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810516
bnc691fda62016-08-12 00:43:1610517 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210518 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810519
wezca1070932016-05-26 20:30:5210520 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810521 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10522
10523 std::string response_data;
bnc691fda62016-08-12 00:43:1610524 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110525 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810526 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910527
10528 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610529 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910530 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710531}
10532
10533// Make sure that a dropped connection while draining the body for auth
10534// restart does the right thing.
bncd16676a2016-07-20 16:23:0110535TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710536 HttpRequestInfo request;
10537 request.method = "GET";
bncce36dca22015-04-21 22:11:2310538 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010539 request.traffic_annotation =
10540 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710541
10542 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310543 MockWrite(
10544 "GET / HTTP/1.1\r\n"
10545 "Host: www.example.org\r\n"
10546 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710547 };
10548
10549 MockRead data_reads1[] = {
10550 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10551 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10553 MockRead("Content-Length: 14\r\n\r\n"),
10554 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610555 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710556 };
10557
[email protected]31a2bfe2010-02-09 08:03:3910558 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10559 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710561
bnc691fda62016-08-12 00:43:1610562 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710563 // be issuing -- the final header line contains the credentials.
10564 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310565 MockWrite(
10566 "GET / HTTP/1.1\r\n"
10567 "Host: www.example.org\r\n"
10568 "Connection: keep-alive\r\n"
10569 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710570 };
10571
10572 // Lastly, the server responds with the actual content.
10573 MockRead data_reads2[] = {
10574 MockRead("HTTP/1.1 200 OK\r\n"),
10575 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10576 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610577 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710578 };
10579
[email protected]31a2bfe2010-02-09 08:03:3910580 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10581 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710582 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710584
[email protected]49639fa2011-12-20 23:22:4110585 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710586
bnc691fda62016-08-12 00:43:1610587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010588
tfarina42834112016-09-22 13:38:2010589 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710591
10592 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110593 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710594
bnc691fda62016-08-12 00:43:1610595 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210596 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410597 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710598
[email protected]49639fa2011-12-20 23:22:4110599 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710600
bnc691fda62016-08-12 00:43:1610601 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710603
10604 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110605 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710606
bnc691fda62016-08-12 00:43:1610607 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210608 ASSERT_TRUE(response);
10609 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710610 EXPECT_EQ(100, response->headers->GetContentLength());
10611}
10612
10613// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110614TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Lily Houghton8c2f97d2018-01-22 05:06:5910615 session_deps_.proxy_resolution_service =
10616 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710617
10618 HttpRequestInfo request;
10619 request.method = "GET";
bncce36dca22015-04-21 22:11:2310620 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010621 request.traffic_annotation =
10622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710623
10624 MockRead proxy_reads[] = {
10625 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610626 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710627 };
10628
[email protected]31a2bfe2010-02-09 08:03:3910629 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610630 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710631
[email protected]bb88e1d32013-05-03 23:11:0710632 session_deps_.socket_factory->AddSocketDataProvider(&data);
10633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710634
[email protected]49639fa2011-12-20 23:22:4110635 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710636
[email protected]bb88e1d32013-05-03 23:11:0710637 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710638
danakj1fd259a02016-04-16 03:17:0910639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710641
tfarina42834112016-09-22 13:38:2010642 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710644
10645 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110646 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710647}
10648
bncd16676a2016-07-20 16:23:0110649TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610650 HttpRequestInfo request;
10651 request.method = "GET";
bncce36dca22015-04-21 22:11:2310652 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010653 request.traffic_annotation =
10654 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610655
danakj1fd259a02016-04-16 03:17:0910656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710658
[email protected]e22e1362009-11-23 21:31:1210659 MockRead data_reads[] = {
10660 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610661 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210662 };
[email protected]9492e4a2010-02-24 00:58:4610663
10664 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710665 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610666
[email protected]49639fa2011-12-20 23:22:4110667 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610668
tfarina42834112016-09-22 13:38:2010669 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610671
robpercival214763f2016-07-01 23:27:0110672 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610673
bnc691fda62016-08-12 00:43:1610674 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210675 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610676
wezca1070932016-05-26 20:30:5210677 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610678 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10679
10680 std::string response_data;
bnc691fda62016-08-12 00:43:1610681 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110682 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210683}
10684
bncd16676a2016-07-20 16:23:0110685TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510686 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210687 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410688 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110689 UploadFileElementReader::ScopedOverridingContentLengthForTests
10690 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310691
danakj1fd259a02016-04-16 03:17:0910692 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910693 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410694 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710695 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210696 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710697
10698 HttpRequestInfo request;
10699 request.method = "POST";
bncce36dca22015-04-21 22:11:2310700 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710701 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010702 request.traffic_annotation =
10703 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710704
danakj1fd259a02016-04-16 03:17:0910705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310707
10708 MockRead data_reads[] = {
10709 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10710 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610711 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310712 };
[email protected]31a2bfe2010-02-09 08:03:3910713 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710714 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310715
[email protected]49639fa2011-12-20 23:22:4110716 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310717
tfarina42834112016-09-22 13:38:2010718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310720
10721 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110722 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310723
bnc691fda62016-08-12 00:43:1610724 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210725 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310726
maksim.sisove869bf52016-06-23 17:11:5210727 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310728
[email protected]dd3aa792013-07-16 19:10:2310729 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310730}
10731
bncd16676a2016-07-20 16:23:0110732TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510733 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210734 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610735 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810736 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10737 base::WriteFile(temp_file, temp_file_content.c_str(),
10738 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110739 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610740
danakj1fd259a02016-04-16 03:17:0910741 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910742 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410743 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710744 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210745 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710746
10747 HttpRequestInfo request;
10748 request.method = "POST";
bncce36dca22015-04-21 22:11:2310749 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710750 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010751 request.traffic_annotation =
10752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710753
[email protected]999dd8c2013-11-12 06:45:5410754 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610757
[email protected]999dd8c2013-11-12 06:45:5410758 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710759 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610760
[email protected]49639fa2011-12-20 23:22:4110761 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610762
tfarina42834112016-09-22 13:38:2010763 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610765
10766 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110767 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610768
[email protected]dd3aa792013-07-16 19:10:2310769 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610770}
10771
bncd16676a2016-07-20 16:23:0110772TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310773 class FakeUploadElementReader : public UploadElementReader {
10774 public:
Chris Watkins7a41d3552017-12-01 02:13:2710775 FakeUploadElementReader() = default;
10776 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310777
Matt Menkecc1d3a902018-02-05 18:27:3310778 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310779
10780 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310781 int Init(CompletionOnceCallback callback) override {
10782 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310783 return ERR_IO_PENDING;
10784 }
avibf0746c2015-12-09 19:53:1410785 uint64_t GetContentLength() const override { return 0; }
10786 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010787 int Read(IOBuffer* buf,
10788 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310789 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310790 return ERR_FAILED;
10791 }
10792
10793 private:
Matt Menkecc1d3a902018-02-05 18:27:3310794 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310795 };
10796
10797 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910798 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10799 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210800 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310801
10802 HttpRequestInfo request;
10803 request.method = "POST";
bncce36dca22015-04-21 22:11:2310804 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310805 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010806 request.traffic_annotation =
10807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310808
danakj1fd259a02016-04-16 03:17:0910809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810810 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910811 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310812
10813 StaticSocketDataProvider data;
10814 session_deps_.socket_factory->AddSocketDataProvider(&data);
10815
10816 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010817 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510819 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310820
10821 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310822 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10823 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310824
10825 // Return Init()'s result after the transaction gets destroyed.
10826 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310827 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310828}
10829
[email protected]aeefc9e82010-02-19 16:18:2710830// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110831TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710832 HttpRequestInfo request;
10833 request.method = "GET";
bncce36dca22015-04-21 22:11:2310834 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010835 request.traffic_annotation =
10836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710837
10838 // First transaction will request a resource and receive a Basic challenge
10839 // with realm="first_realm".
10840 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310841 MockWrite(
10842 "GET / HTTP/1.1\r\n"
10843 "Host: www.example.org\r\n"
10844 "Connection: keep-alive\r\n"
10845 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710846 };
10847 MockRead data_reads1[] = {
10848 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10849 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10850 "\r\n"),
10851 };
10852
bnc691fda62016-08-12 00:43:1610853 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710854 // for first_realm. The server will reject and provide a challenge with
10855 // second_realm.
10856 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310857 MockWrite(
10858 "GET / HTTP/1.1\r\n"
10859 "Host: www.example.org\r\n"
10860 "Connection: keep-alive\r\n"
10861 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10862 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710863 };
10864 MockRead data_reads2[] = {
10865 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10866 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10867 "\r\n"),
10868 };
10869
10870 // This again fails, and goes back to first_realm. Make sure that the
10871 // entry is removed from cache.
10872 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310873 MockWrite(
10874 "GET / HTTP/1.1\r\n"
10875 "Host: www.example.org\r\n"
10876 "Connection: keep-alive\r\n"
10877 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10878 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710879 };
10880 MockRead data_reads3[] = {
10881 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10882 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10883 "\r\n"),
10884 };
10885
10886 // Try one last time (with the correct password) and get the resource.
10887 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310888 MockWrite(
10889 "GET / HTTP/1.1\r\n"
10890 "Host: www.example.org\r\n"
10891 "Connection: keep-alive\r\n"
10892 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10893 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710894 };
10895 MockRead data_reads4[] = {
10896 MockRead("HTTP/1.1 200 OK\r\n"
10897 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010898 "Content-Length: 5\r\n"
10899 "\r\n"
10900 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710901 };
10902
10903 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10904 data_writes1, arraysize(data_writes1));
10905 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10906 data_writes2, arraysize(data_writes2));
10907 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10908 data_writes3, arraysize(data_writes3));
10909 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10910 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710911 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10912 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10913 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10914 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710915
[email protected]49639fa2011-12-20 23:22:4110916 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710917
danakj1fd259a02016-04-16 03:17:0910918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010920
[email protected]aeefc9e82010-02-19 16:18:2710921 // Issue the first request with Authorize headers. There should be a
10922 // password prompt for first_realm waiting to be filled in after the
10923 // transaction completes.
tfarina42834112016-09-22 13:38:2010924 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710926 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110927 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210929 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410930 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210931 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410932 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310933 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410934 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910935 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710936
10937 // Issue the second request with an incorrect password. There should be a
10938 // password prompt for second_realm waiting to be filled in after the
10939 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110940 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610941 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10942 callback2.callback());
robpercival214763f2016-07-01 23:27:0110943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710944 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110945 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610946 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210947 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410948 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210949 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410950 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310951 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410952 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910953 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710954
10955 // Issue the third request with another incorrect password. There should be
10956 // a password prompt for first_realm waiting to be filled in. If the password
10957 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10958 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110959 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610960 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10961 callback3.callback());
robpercival214763f2016-07-01 23:27:0110962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710963 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110964 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610965 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210966 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410967 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210968 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410969 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310970 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410971 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910972 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710973
10974 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110975 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610976 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10977 callback4.callback());
robpercival214763f2016-07-01 23:27:0110978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710979 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110980 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610981 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210982 ASSERT_TRUE(response);
10983 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710984}
10985
Bence Béky230ac612017-08-30 19:17:0810986// Regression test for https://crbug.com/754395.
10987TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10988 MockRead data_reads[] = {
10989 MockRead("HTTP/1.1 200 OK\r\n"),
10990 MockRead(kAlternativeServiceHttpHeader),
10991 MockRead("\r\n"),
10992 MockRead("hello world"),
10993 MockRead(SYNCHRONOUS, OK),
10994 };
10995
10996 HttpRequestInfo request;
10997 request.method = "GET";
10998 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010999 request.traffic_annotation =
11000 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811001
11002 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11003 session_deps_.socket_factory->AddSocketDataProvider(&data);
11004
11005 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911006 ssl.ssl_info.cert =
11007 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11008 ASSERT_TRUE(ssl.ssl_info.cert);
11009 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11011
11012 TestCompletionCallback callback;
11013
11014 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11016
11017 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11019
11020 url::SchemeHostPort test_server(request.url);
11021 HttpServerProperties* http_server_properties =
11022 session->http_server_properties();
11023 EXPECT_TRUE(
11024 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11025
11026 EXPECT_THAT(callback.WaitForResult(), IsOk());
11027
11028 const HttpResponseInfo* response = trans.GetResponseInfo();
11029 ASSERT_TRUE(response);
11030 ASSERT_TRUE(response->headers);
11031 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11032 EXPECT_FALSE(response->was_fetched_via_spdy);
11033 EXPECT_FALSE(response->was_alpn_negotiated);
11034
11035 std::string response_data;
11036 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11037 EXPECT_EQ("hello world", response_data);
11038
11039 EXPECT_TRUE(
11040 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11041}
11042
bncd16676a2016-07-20 16:23:0111043TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211044 MockRead data_reads[] = {
11045 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311046 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211047 MockRead("\r\n"),
11048 MockRead("hello world"),
11049 MockRead(SYNCHRONOUS, OK),
11050 };
11051
11052 HttpRequestInfo request;
11053 request.method = "GET";
bncb26024382016-06-29 02:39:4511054 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011055 request.traffic_annotation =
11056 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211057
11058 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211059 session_deps_.socket_factory->AddSocketDataProvider(&data);
11060
bncb26024382016-06-29 02:39:4511061 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911062 ssl.ssl_info.cert =
11063 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11064 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11066
bncc958faa2015-07-31 18:14:5211067 TestCompletionCallback callback;
11068
danakj1fd259a02016-04-16 03:17:0911069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211071
tfarina42834112016-09-22 13:38:2011072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211074
bncb26024382016-06-29 02:39:4511075 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011076 HttpServerProperties* http_server_properties =
11077 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411078 EXPECT_TRUE(
11079 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211080
robpercival214763f2016-07-01 23:27:0111081 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211082
bnc691fda62016-08-12 00:43:1611083 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211084 ASSERT_TRUE(response);
11085 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11087 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211088 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211089
11090 std::string response_data;
bnc691fda62016-08-12 00:43:1611091 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211092 EXPECT_EQ("hello world", response_data);
11093
zhongyic4de03032017-05-19 04:07:3411094 AlternativeServiceInfoVector alternative_service_info_vector =
11095 http_server_properties->GetAlternativeServiceInfos(test_server);
11096 ASSERT_EQ(1u, alternative_service_info_vector.size());
11097 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11098 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411099 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211100}
11101
bnce3dd56f2016-06-01 10:37:1111102// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111103TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111104 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111105 MockRead data_reads[] = {
11106 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311107 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111108 MockRead("\r\n"),
11109 MockRead("hello world"),
11110 MockRead(SYNCHRONOUS, OK),
11111 };
11112
11113 HttpRequestInfo request;
11114 request.method = "GET";
11115 request.url = GURL("http://www.example.org/");
11116 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011117 request.traffic_annotation =
11118 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111119
11120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11121 session_deps_.socket_factory->AddSocketDataProvider(&data);
11122
11123 TestCompletionCallback callback;
11124
11125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111127
11128 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011129 HttpServerProperties* http_server_properties =
11130 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411131 EXPECT_TRUE(
11132 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111133
tfarina42834112016-09-22 13:38:2011134 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111135 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11136 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111137
bnc691fda62016-08-12 00:43:1611138 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111139 ASSERT_TRUE(response);
11140 ASSERT_TRUE(response->headers);
11141 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11142 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211143 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111144
11145 std::string response_data;
bnc691fda62016-08-12 00:43:1611146 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111147 EXPECT_EQ("hello world", response_data);
11148
zhongyic4de03032017-05-19 04:07:3411149 EXPECT_TRUE(
11150 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111151}
11152
bnca86731e2017-04-17 12:31:2811153// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511154// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111155TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511156 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811157 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511158
bnc8bef8da22016-05-30 01:28:2511159 HttpRequestInfo request;
11160 request.method = "GET";
bncb26024382016-06-29 02:39:4511161 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511162 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011163 request.traffic_annotation =
11164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511165
11166 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11167 StaticSocketDataProvider first_data;
11168 first_data.set_connect_data(mock_connect);
11169 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511170 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611171 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511173
11174 MockRead data_reads[] = {
11175 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11176 MockRead(ASYNC, OK),
11177 };
11178 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11179 0);
11180 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11181
11182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11183
bnc525e175a2016-06-20 12:36:4011184 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511185 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111186 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11187 444);
bnc8bef8da22016-05-30 01:28:2511188 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111189 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511190 url::SchemeHostPort(request.url), alternative_service, expiration);
11191
bnc691fda62016-08-12 00:43:1611192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511193 TestCompletionCallback callback;
11194
tfarina42834112016-09-22 13:38:2011195 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511196 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111197 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511198}
11199
bnce3dd56f2016-06-01 10:37:1111200// Regression test for https://crbug.com/615497:
11201// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111202TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111203 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111204 HttpRequestInfo request;
11205 request.method = "GET";
11206 request.url = GURL("http://www.example.org/");
11207 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011208 request.traffic_annotation =
11209 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111210
11211 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11212 StaticSocketDataProvider first_data;
11213 first_data.set_connect_data(mock_connect);
11214 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11215
11216 MockRead data_reads[] = {
11217 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11218 MockRead(ASYNC, OK),
11219 };
11220 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
11221 0);
11222 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11223
11224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11225
bnc525e175a2016-06-20 12:36:4011226 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111227 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111228 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111229 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111230 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111231 url::SchemeHostPort(request.url), alternative_service, expiration);
11232
bnc691fda62016-08-12 00:43:1611233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111234 TestCompletionCallback callback;
11235
tfarina42834112016-09-22 13:38:2011236 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111237 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111238 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111239}
11240
bncd16676a2016-07-20 16:23:0111241TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811242 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011244 HttpServerProperties* http_server_properties =
11245 session->http_server_properties();
bncb26024382016-06-29 02:39:4511246 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111247 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811248 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111249 http_server_properties->SetQuicAlternativeService(
11250 test_server, alternative_service, expiration,
11251 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411252 EXPECT_EQ(
11253 1u,
11254 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811255
11256 // Send a clear header.
11257 MockRead data_reads[] = {
11258 MockRead("HTTP/1.1 200 OK\r\n"),
11259 MockRead("Alt-Svc: clear\r\n"),
11260 MockRead("\r\n"),
11261 MockRead("hello world"),
11262 MockRead(SYNCHRONOUS, OK),
11263 };
11264 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
11265 session_deps_.socket_factory->AddSocketDataProvider(&data);
11266
bncb26024382016-06-29 02:39:4511267 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911268 ssl.ssl_info.cert =
11269 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11270 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11272
bnc4f575852015-10-14 18:35:0811273 HttpRequestInfo request;
11274 request.method = "GET";
bncb26024382016-06-29 02:39:4511275 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011276 request.traffic_annotation =
11277 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811278
11279 TestCompletionCallback callback;
11280
bnc691fda62016-08-12 00:43:1611281 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811282
tfarina42834112016-09-22 13:38:2011283 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111284 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811285
bnc691fda62016-08-12 00:43:1611286 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211287 ASSERT_TRUE(response);
11288 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811289 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11290 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211291 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811292
11293 std::string response_data;
bnc691fda62016-08-12 00:43:1611294 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811295 EXPECT_EQ("hello world", response_data);
11296
zhongyic4de03032017-05-19 04:07:3411297 EXPECT_TRUE(
11298 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811299}
11300
bncd16676a2016-07-20 16:23:0111301TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211302 MockRead data_reads[] = {
11303 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311304 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11305 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211306 MockRead("hello world"),
11307 MockRead(SYNCHRONOUS, OK),
11308 };
11309
11310 HttpRequestInfo request;
11311 request.method = "GET";
bncb26024382016-06-29 02:39:4511312 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011313 request.traffic_annotation =
11314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211315
11316 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211317 session_deps_.socket_factory->AddSocketDataProvider(&data);
11318
bncb26024382016-06-29 02:39:4511319 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911320 ssl.ssl_info.cert =
11321 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11322 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511323 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11324
bncc958faa2015-07-31 18:14:5211325 TestCompletionCallback callback;
11326
danakj1fd259a02016-04-16 03:17:0911327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611328 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211329
tfarina42834112016-09-22 13:38:2011330 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211332
bncb26024382016-06-29 02:39:4511333 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011334 HttpServerProperties* http_server_properties =
11335 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411336 EXPECT_TRUE(
11337 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211338
robpercival214763f2016-07-01 23:27:0111339 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211340
bnc691fda62016-08-12 00:43:1611341 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211342 ASSERT_TRUE(response);
11343 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211344 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11345 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211346 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211347
11348 std::string response_data;
bnc691fda62016-08-12 00:43:1611349 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211350 EXPECT_EQ("hello world", response_data);
11351
zhongyic4de03032017-05-19 04:07:3411352 AlternativeServiceInfoVector alternative_service_info_vector =
11353 http_server_properties->GetAlternativeServiceInfos(test_server);
11354 ASSERT_EQ(2u, alternative_service_info_vector.size());
11355
11356 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11357 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411358 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411359 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11360 1234);
11361 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411362 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211363}
11364
bncd16676a2016-07-20 16:23:0111365TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611366 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211367 HostPortPair alternative("alternative.example.org", 443);
11368 std::string origin_url = "https://origin.example.org:443";
11369 std::string alternative_url = "https://alternative.example.org:443";
11370
11371 // Negotiate HTTP/1.1 with alternative.example.org.
11372 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611373 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11375
11376 // HTTP/1.1 data for request.
11377 MockWrite http_writes[] = {
11378 MockWrite("GET / HTTP/1.1\r\n"
11379 "Host: alternative.example.org\r\n"
11380 "Connection: keep-alive\r\n\r\n"),
11381 };
11382
11383 MockRead http_reads[] = {
11384 MockRead("HTTP/1.1 200 OK\r\n"
11385 "Content-Type: text/html; charset=iso-8859-1\r\n"
11386 "Content-Length: 40\r\n\r\n"
11387 "first HTTP/1.1 response from alternative"),
11388 };
11389 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11390 http_writes, arraysize(http_writes));
11391 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11392
11393 StaticSocketDataProvider data_refused;
11394 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11395 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11396
zhongyi3d4a55e72016-04-22 20:36:4611397 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911398 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011399 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211400 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111401 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211402 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111403 http_server_properties->SetQuicAlternativeService(
11404 server, alternative_service, expiration,
11405 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211406 // Mark the QUIC alternative service as broken.
11407 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11408
zhongyi48704c182015-12-07 07:52:0211409 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211411 request.method = "GET";
11412 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011413 request.traffic_annotation =
11414 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11415
zhongyi48704c182015-12-07 07:52:0211416 TestCompletionCallback callback;
11417 NetErrorDetails details;
11418 EXPECT_FALSE(details.quic_broken);
11419
tfarina42834112016-09-22 13:38:2011420 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611421 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211422 EXPECT_TRUE(details.quic_broken);
11423}
11424
bncd16676a2016-07-20 16:23:0111425TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611426 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211427 HostPortPair alternative1("alternative1.example.org", 443);
11428 HostPortPair alternative2("alternative2.example.org", 443);
11429 std::string origin_url = "https://origin.example.org:443";
11430 std::string alternative_url1 = "https://alternative1.example.org:443";
11431 std::string alternative_url2 = "https://alternative2.example.org:443";
11432
11433 // Negotiate HTTP/1.1 with alternative1.example.org.
11434 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611435 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11437
11438 // HTTP/1.1 data for request.
11439 MockWrite http_writes[] = {
11440 MockWrite("GET / HTTP/1.1\r\n"
11441 "Host: alternative1.example.org\r\n"
11442 "Connection: keep-alive\r\n\r\n"),
11443 };
11444
11445 MockRead http_reads[] = {
11446 MockRead("HTTP/1.1 200 OK\r\n"
11447 "Content-Type: text/html; charset=iso-8859-1\r\n"
11448 "Content-Length: 40\r\n\r\n"
11449 "first HTTP/1.1 response from alternative1"),
11450 };
11451 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11452 http_writes, arraysize(http_writes));
11453 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11454
11455 StaticSocketDataProvider data_refused;
11456 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11457 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11458
danakj1fd259a02016-04-16 03:17:0911459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011460 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211461 session->http_server_properties();
11462
zhongyi3d4a55e72016-04-22 20:36:4611463 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211464 AlternativeServiceInfoVector alternative_service_info_vector;
11465 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11466
bnc3472afd2016-11-17 15:27:2111467 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111468 alternative_service_info_vector.push_back(
11469 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11470 alternative_service1, expiration,
11471 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111472 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111473 alternative_service_info_vector.push_back(
11474 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11475 alternative_service2, expiration,
11476 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211477
11478 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611479 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211480
11481 // Mark one of the QUIC alternative service as broken.
11482 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411483 EXPECT_EQ(2u,
11484 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211485
zhongyi48704c182015-12-07 07:52:0211486 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611487 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211488 request.method = "GET";
11489 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011490 request.traffic_annotation =
11491 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11492
zhongyi48704c182015-12-07 07:52:0211493 TestCompletionCallback callback;
11494 NetErrorDetails details;
11495 EXPECT_FALSE(details.quic_broken);
11496
tfarina42834112016-09-22 13:38:2011497 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611498 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211499 EXPECT_FALSE(details.quic_broken);
11500}
11501
bncd16676a2016-07-20 16:23:0111502TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211503 HttpRequestInfo request;
11504 request.method = "GET";
bncb26024382016-06-29 02:39:4511505 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011506 request.traffic_annotation =
11507 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211508
[email protected]d973e99a2012-02-17 21:02:3611509 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211510 StaticSocketDataProvider first_data;
11511 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711512 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511513 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611514 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511515 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211516
11517 MockRead data_reads[] = {
11518 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11519 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611520 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211521 };
11522 StaticSocketDataProvider second_data(
11523 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711524 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211525
danakj1fd259a02016-04-16 03:17:0911526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211527
bnc525e175a2016-06-20 12:36:4011528 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311529 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611530 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111531 // Port must be < 1024, or the header will be ignored (since initial port was
11532 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111533 // Port is ignored by MockConnect anyway.
11534 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11535 666);
bnc7dc7e1b42015-07-28 14:43:1211536 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111537 http_server_properties->SetHttp2AlternativeService(
11538 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211539
bnc691fda62016-08-12 00:43:1611540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111541 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211542
tfarina42834112016-09-22 13:38:2011543 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11545 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211546
bnc691fda62016-08-12 00:43:1611547 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211548 ASSERT_TRUE(response);
11549 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211550 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11551
11552 std::string response_data;
bnc691fda62016-08-12 00:43:1611553 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211554 EXPECT_EQ("hello world", response_data);
11555
zhongyic4de03032017-05-19 04:07:3411556 const AlternativeServiceInfoVector alternative_service_info_vector =
11557 http_server_properties->GetAlternativeServiceInfos(server);
11558 ASSERT_EQ(1u, alternative_service_info_vector.size());
11559 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411560 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411561 EXPECT_TRUE(
11562 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211563}
11564
bnc55ff9da2015-08-19 18:42:3511565// Ensure that we are not allowed to redirect traffic via an alternate protocol
11566// to an unrestricted (port >= 1024) when the original traffic was on a
11567// restricted port (port < 1024). Ensure that we can redirect in all other
11568// cases.
bncd16676a2016-07-20 16:23:0111569TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111570 HttpRequestInfo restricted_port_request;
11571 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511572 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111573 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011574 restricted_port_request.traffic_annotation =
11575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111576
[email protected]d973e99a2012-02-17 21:02:3611577 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111578 StaticSocketDataProvider first_data;
11579 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711580 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111581
11582 MockRead data_reads[] = {
11583 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11584 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611585 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111586 };
11587 StaticSocketDataProvider second_data(
11588 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711589 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511590 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611591 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111593
danakj1fd259a02016-04-16 03:17:0911594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111595
bnc525e175a2016-06-20 12:36:4011596 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311597 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111598 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111599 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11600 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211601 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111602 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611603 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011604 expiration);
[email protected]3912662a32011-10-04 00:51:1111605
bnc691fda62016-08-12 00:43:1611606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111607 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111608
tfarina42834112016-09-22 13:38:2011609 int rv = trans.Start(&restricted_port_request, callback.callback(),
11610 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111612 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111613 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911614}
[email protected]3912662a32011-10-04 00:51:1111615
bnc55ff9da2015-08-19 18:42:3511616// Ensure that we are allowed to redirect traffic via an alternate protocol to
11617// an unrestricted (port >= 1024) when the original traffic was on a restricted
11618// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111619TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711620 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911621
11622 HttpRequestInfo restricted_port_request;
11623 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511624 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911625 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011626 restricted_port_request.traffic_annotation =
11627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911628
11629 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11630 StaticSocketDataProvider first_data;
11631 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711632 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911633
11634 MockRead data_reads[] = {
11635 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11636 MockRead("hello world"),
11637 MockRead(ASYNC, OK),
11638 };
11639 StaticSocketDataProvider second_data(
11640 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711641 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511642 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611643 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911645
danakj1fd259a02016-04-16 03:17:0911646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911647
bnc525e175a2016-06-20 12:36:4011648 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911649 session->http_server_properties();
11650 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111651 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11652 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211653 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111654 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611655 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011656 expiration);
[email protected]c54c6962013-02-01 04:53:1911657
bnc691fda62016-08-12 00:43:1611658 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911659 TestCompletionCallback callback;
11660
tfarina42834112016-09-22 13:38:2011661 EXPECT_EQ(ERR_IO_PENDING,
11662 trans.Start(&restricted_port_request, callback.callback(),
11663 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911664 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111665 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111666}
11667
bnc55ff9da2015-08-19 18:42:3511668// Ensure that we are not allowed to redirect traffic via an alternate protocol
11669// to an unrestricted (port >= 1024) when the original traffic was on a
11670// restricted port (port < 1024). Ensure that we can redirect in all other
11671// cases.
bncd16676a2016-07-20 16:23:0111672TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111673 HttpRequestInfo restricted_port_request;
11674 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511675 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111676 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011677 restricted_port_request.traffic_annotation =
11678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111679
[email protected]d973e99a2012-02-17 21:02:3611680 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111681 StaticSocketDataProvider first_data;
11682 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711683 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111684
11685 MockRead data_reads[] = {
11686 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11687 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611688 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111689 };
11690 StaticSocketDataProvider second_data(
11691 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711692 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111693
bncb26024382016-06-29 02:39:4511694 SSLSocketDataProvider ssl(ASYNC, OK);
11695 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11696
danakj1fd259a02016-04-16 03:17:0911697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111698
bnc525e175a2016-06-20 12:36:4011699 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311700 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111701 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111702 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11703 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211704 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111705 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611706 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011707 expiration);
[email protected]3912662a32011-10-04 00:51:1111708
bnc691fda62016-08-12 00:43:1611709 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111710 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111711
tfarina42834112016-09-22 13:38:2011712 int rv = trans.Start(&restricted_port_request, callback.callback(),
11713 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111715 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111716 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111717}
11718
bnc55ff9da2015-08-19 18:42:3511719// Ensure that we are not allowed to redirect traffic via an alternate protocol
11720// to an unrestricted (port >= 1024) when the original traffic was on a
11721// restricted port (port < 1024). Ensure that we can redirect in all other
11722// cases.
bncd16676a2016-07-20 16:23:0111723TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111724 HttpRequestInfo unrestricted_port_request;
11725 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511726 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111727 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011728 unrestricted_port_request.traffic_annotation =
11729 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111730
[email protected]d973e99a2012-02-17 21:02:3611731 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111732 StaticSocketDataProvider first_data;
11733 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711734 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111735
11736 MockRead data_reads[] = {
11737 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11738 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611739 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111740 };
11741 StaticSocketDataProvider second_data(
11742 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711743 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511744 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611745 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511746 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111747
danakj1fd259a02016-04-16 03:17:0911748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111749
bnc525e175a2016-06-20 12:36:4011750 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311751 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111752 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111753 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11754 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211755 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111756 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611757 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011758 expiration);
[email protected]3912662a32011-10-04 00:51:1111759
bnc691fda62016-08-12 00:43:1611760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111761 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111762
bnc691fda62016-08-12 00:43:1611763 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011764 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111766 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111767 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111768}
11769
bnc55ff9da2015-08-19 18:42:3511770// Ensure that we are not allowed to redirect traffic via an alternate protocol
11771// to an unrestricted (port >= 1024) when the original traffic was on a
11772// restricted port (port < 1024). Ensure that we can redirect in all other
11773// cases.
bncd16676a2016-07-20 16:23:0111774TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111775 HttpRequestInfo unrestricted_port_request;
11776 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511777 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111778 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011779 unrestricted_port_request.traffic_annotation =
11780 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111781
[email protected]d973e99a2012-02-17 21:02:3611782 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111783 StaticSocketDataProvider first_data;
11784 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711785 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111786
11787 MockRead data_reads[] = {
11788 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11789 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611790 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111791 };
11792 StaticSocketDataProvider second_data(
11793 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711794 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111795
bncb26024382016-06-29 02:39:4511796 SSLSocketDataProvider ssl(ASYNC, OK);
11797 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11798
danakj1fd259a02016-04-16 03:17:0911799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111800
bnc525e175a2016-06-20 12:36:4011801 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311802 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211803 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111804 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11805 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211806 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111807 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611808 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011809 expiration);
[email protected]3912662a32011-10-04 00:51:1111810
bnc691fda62016-08-12 00:43:1611811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111812 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111813
bnc691fda62016-08-12 00:43:1611814 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011815 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111817 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111818 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111819}
11820
bnc55ff9da2015-08-19 18:42:3511821// Ensure that we are not allowed to redirect traffic via an alternate protocol
11822// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11823// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111824TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211825 HttpRequestInfo request;
11826 request.method = "GET";
bncce36dca22015-04-21 22:11:2311827 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011828 request.traffic_annotation =
11829 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211830
11831 // The alternate protocol request will error out before we attempt to connect,
11832 // so only the standard HTTP request will try to connect.
11833 MockRead data_reads[] = {
11834 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11835 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611836 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211837 };
11838 StaticSocketDataProvider data(
11839 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711840 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211841
danakj1fd259a02016-04-16 03:17:0911842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211843
bnc525e175a2016-06-20 12:36:4011844 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211845 session->http_server_properties();
11846 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111847 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11848 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211849 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111850 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611851 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211852
bnc691fda62016-08-12 00:43:1611853 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211854 TestCompletionCallback callback;
11855
tfarina42834112016-09-22 13:38:2011856 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211858 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111859 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211860
bnc691fda62016-08-12 00:43:1611861 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211862 ASSERT_TRUE(response);
11863 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211864 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11865
11866 std::string response_data;
bnc691fda62016-08-12 00:43:1611867 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211868 EXPECT_EQ("hello world", response_data);
11869}
11870
bncd16676a2016-07-20 16:23:0111871TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411872 HttpRequestInfo request;
11873 request.method = "GET";
bncb26024382016-06-29 02:39:4511874 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011875 request.traffic_annotation =
11876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411877
11878 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211879 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311880 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211881 MockRead("\r\n"),
11882 MockRead("hello world"),
11883 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11884 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411885
11886 StaticSocketDataProvider first_transaction(
11887 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711888 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511889 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611890 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411892
bnc032658ba2016-09-26 18:17:1511893 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411894
bncdf80d44fd2016-07-15 20:27:4111895 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511896 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111897 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411898
bnc42331402016-07-25 13:36:1511899 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111900 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411901 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111902 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411903 };
11904
rch8e6c6c42015-05-01 14:05:1311905 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11906 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711907 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411908
[email protected]d973e99a2012-02-17 21:02:3611909 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511910 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11911 NULL, 0, NULL, 0);
11912 hanging_non_alternate_protocol_socket.set_connect_data(
11913 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711914 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511915 &hanging_non_alternate_protocol_socket);
11916
[email protected]49639fa2011-12-20 23:22:4111917 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411918
danakj1fd259a02016-04-16 03:17:0911919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811920 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911921 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411922
tfarina42834112016-09-22 13:38:2011923 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111924 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11925 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411926
11927 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211928 ASSERT_TRUE(response);
11929 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411930 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11931
11932 std::string response_data;
robpercival214763f2016-07-01 23:27:0111933 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411934 EXPECT_EQ("hello world", response_data);
11935
bnc87dcefc2017-05-25 12:47:5811936 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911937 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411938
tfarina42834112016-09-22 13:38:2011939 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11941 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411942
11943 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211944 ASSERT_TRUE(response);
11945 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211946 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311947 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211948 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411949
robpercival214763f2016-07-01 23:27:0111950 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411951 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411952}
11953
bncd16676a2016-07-20 16:23:0111954TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511955 HttpRequestInfo request;
11956 request.method = "GET";
bncb26024382016-06-29 02:39:4511957 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011958 request.traffic_annotation =
11959 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511960
bncb26024382016-06-29 02:39:4511961 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511962 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211963 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311964 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211965 MockRead("\r\n"),
11966 MockRead("hello world"),
11967 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11968 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511969 };
11970
bncb26024382016-06-29 02:39:4511971 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11972 0);
11973 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511974
bncb26024382016-06-29 02:39:4511975 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911976 ssl_http11.ssl_info.cert =
11977 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11978 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511979 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11980
11981 // Second transaction starts an alternative and a non-alternative Job.
11982 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611983 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811984 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11985 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811986 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11987
11988 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11989 hanging_socket2.set_connect_data(never_finishing_connect);
11990 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511991
bncb26024382016-06-29 02:39:4511992 // Third transaction starts an alternative and a non-alternative job.
11993 // The non-alternative job hangs, but the alternative one succeeds.
11994 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111995 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511996 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111997 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511998 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511999 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112000 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512001 };
bnc42331402016-07-25 13:36:1512002 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112003 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512004 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112005 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512006 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112007 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12008 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312009 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512010 };
12011
rch8e6c6c42015-05-01 14:05:1312012 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12013 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712014 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512015
bnc032658ba2016-09-26 18:17:1512016 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512017
mmenkecc2298e2015-12-07 18:20:1812018 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
12019 hanging_socket3.set_connect_data(never_finishing_connect);
12020 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512021
danakj1fd259a02016-04-16 03:17:0912022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112023 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012024 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512025
tfarina42834112016-09-22 13:38:2012026 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12028 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512029
12030 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212031 ASSERT_TRUE(response);
12032 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512033 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12034
12035 std::string response_data;
robpercival214763f2016-07-01 23:27:0112036 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512037 EXPECT_EQ("hello world", response_data);
12038
[email protected]49639fa2011-12-20 23:22:4112039 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012040 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012041 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512043
[email protected]49639fa2011-12-20 23:22:4112044 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012045 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012046 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512048
robpercival214763f2016-07-01 23:27:0112049 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12050 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512051
12052 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212053 ASSERT_TRUE(response);
12054 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212055 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512056 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212057 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112058 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512059 EXPECT_EQ("hello!", response_data);
12060
12061 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212062 ASSERT_TRUE(response);
12063 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212064 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512065 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212066 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112067 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512068 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512069}
12070
bncd16676a2016-07-20 16:23:0112071TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512072 HttpRequestInfo request;
12073 request.method = "GET";
bncb26024382016-06-29 02:39:4512074 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012075 request.traffic_annotation =
12076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512077
12078 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212079 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312080 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212081 MockRead("\r\n"),
12082 MockRead("hello world"),
12083 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12084 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512085 };
12086
12087 StaticSocketDataProvider first_transaction(
12088 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712089 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512090
[email protected]8ddf8322012-02-23 18:08:0612091 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912092 ssl.ssl_info.cert =
12093 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12094 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712095 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512096
[email protected]d973e99a2012-02-17 21:02:3612097 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512098 StaticSocketDataProvider hanging_alternate_protocol_socket(
12099 NULL, 0, NULL, 0);
12100 hanging_alternate_protocol_socket.set_connect_data(
12101 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712102 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512103 &hanging_alternate_protocol_socket);
12104
bncb26024382016-06-29 02:39:4512105 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1812106 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
12107 NULL, 0);
12108 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512109 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512110
[email protected]49639fa2011-12-20 23:22:4112111 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512112
danakj1fd259a02016-04-16 03:17:0912113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812114 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912115 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512116
tfarina42834112016-09-22 13:38:2012117 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12119 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512120
12121 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212122 ASSERT_TRUE(response);
12123 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512124 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12125
12126 std::string response_data;
robpercival214763f2016-07-01 23:27:0112127 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512128 EXPECT_EQ("hello world", response_data);
12129
bnc87dcefc2017-05-25 12:47:5812130 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912131 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512132
tfarina42834112016-09-22 13:38:2012133 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12135 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512136
12137 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212138 ASSERT_TRUE(response);
12139 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512140 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12141 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212142 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512143
robpercival214763f2016-07-01 23:27:0112144 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512145 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512146}
12147
[email protected]631f1322010-04-30 17:59:1112148class CapturingProxyResolver : public ProxyResolver {
12149 public:
Chris Watkins7a41d3552017-12-01 02:13:2712150 CapturingProxyResolver() = default;
12151 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112152
dchengb03027d2014-10-21 12:00:2012153 int GetProxyForURL(const GURL& url,
12154 ProxyInfo* results,
12155 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5512156 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012157 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012158 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12159 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212160 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112161 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212162 return OK;
[email protected]631f1322010-04-30 17:59:1112163 }
12164
[email protected]24476402010-07-20 20:55:1712165 const std::vector<GURL>& resolved() const { return resolved_; }
12166
12167 private:
[email protected]631f1322010-04-30 17:59:1112168 std::vector<GURL> resolved_;
12169
12170 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12171};
12172
sammce64b2362015-04-29 03:50:2312173class CapturingProxyResolverFactory : public ProxyResolverFactory {
12174 public:
12175 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12176 : ProxyResolverFactory(false), resolver_(resolver) {}
12177
12178 int CreateProxyResolver(
12179 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0912180 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2312181 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0912182 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912183 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312184 return OK;
12185 }
12186
12187 private:
12188 ProxyResolver* resolver_;
12189};
12190
bnc2e884782016-08-11 19:45:1912191// Test that proxy is resolved using the origin url,
12192// regardless of the alternative server.
12193TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12194 // Configure proxy to bypass www.example.org, which is the origin URL.
12195 ProxyConfig proxy_config;
12196 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12197 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
12198 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1912199 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1912200
12201 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912202 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912203 &capturing_proxy_resolver);
12204
12205 TestNetLog net_log;
12206
Lily Houghton8c2f97d2018-01-22 05:06:5912207 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1912208 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12209 &net_log);
12210
12211 session_deps_.net_log = &net_log;
12212
12213 // Configure alternative service with a hostname that is not bypassed by the
12214 // proxy.
12215 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12216 HttpServerProperties* http_server_properties =
12217 session->http_server_properties();
12218 url::SchemeHostPort server("https", "www.example.org", 443);
12219 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112220 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912221 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112222 http_server_properties->SetHttp2AlternativeService(
12223 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912224
12225 // Non-alternative job should hang.
12226 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
12227 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
12228 nullptr, 0);
12229 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12230 session_deps_.socket_factory->AddSocketDataProvider(
12231 &hanging_alternate_protocol_socket);
12232
bnc032658ba2016-09-26 18:17:1512233 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912234
12235 HttpRequestInfo request;
12236 request.method = "GET";
12237 request.url = GURL("https://www.example.org/");
12238 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012239 request.traffic_annotation =
12240 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912241
12242 SpdySerializedFrame req(
12243 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12244
12245 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12246
12247 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12248 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
12249 MockRead spdy_reads[] = {
12250 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12251 };
12252
12253 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12254 arraysize(spdy_writes));
12255 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12256
12257 TestCompletionCallback callback;
12258
12259 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12260
tfarina42834112016-09-22 13:38:2012261 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912262 EXPECT_THAT(callback.GetResult(rv), IsOk());
12263
12264 const HttpResponseInfo* response = trans.GetResponseInfo();
12265 ASSERT_TRUE(response);
12266 ASSERT_TRUE(response->headers);
12267 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12268 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212269 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912270
12271 std::string response_data;
12272 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12273 EXPECT_EQ("hello!", response_data);
12274
12275 // Origin host bypasses proxy, no resolution should have happened.
12276 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12277}
12278
bncd16676a2016-07-20 16:23:0112279TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112280 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212281 proxy_config.set_auto_detect(true);
12282 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112283
sammc5dd160c2015-04-02 02:43:1312284 CapturingProxyResolver capturing_proxy_resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5912285 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1912286 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
12287 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5812288 &capturing_proxy_resolver),
12289 nullptr);
vishal.b62985ca92015-04-17 08:45:5112290 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712291 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112292
12293 HttpRequestInfo request;
12294 request.method = "GET";
bncb26024382016-06-29 02:39:4512295 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012296 request.traffic_annotation =
12297 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112298
12299 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212300 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312301 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212302 MockRead("\r\n"),
12303 MockRead("hello world"),
12304 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12305 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112306 };
12307
12308 StaticSocketDataProvider first_transaction(
12309 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712310 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512311 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612312 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112314
bnc032658ba2016-09-26 18:17:1512315 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112316
bncdf80d44fd2016-07-15 20:27:4112317 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512318 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112319 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312320 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512321 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12322 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312323 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112324 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112325 };
12326
[email protected]d911f1b2010-05-05 22:39:4212327 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12328
bnc42331402016-07-25 13:36:1512329 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112330 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112331 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112332 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12333 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112334 };
12335
rch8e6c6c42015-05-01 14:05:1312336 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12337 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712338 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112339
[email protected]d973e99a2012-02-17 21:02:3612340 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512341 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12342 NULL, 0, NULL, 0);
12343 hanging_non_alternate_protocol_socket.set_connect_data(
12344 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712345 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512346 &hanging_non_alternate_protocol_socket);
12347
[email protected]49639fa2011-12-20 23:22:4112348 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112349
danakj1fd259a02016-04-16 03:17:0912350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812351 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912352 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112353
tfarina42834112016-09-22 13:38:2012354 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12356 EXPECT_THAT(callback.WaitForResult(), IsOk());
12357
12358 const HttpResponseInfo* response = trans->GetResponseInfo();
12359 ASSERT_TRUE(response);
12360 ASSERT_TRUE(response->headers);
12361 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12362 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212363 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112364
12365 std::string response_data;
12366 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12367 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112368
bnc87dcefc2017-05-25 12:47:5812369 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912370 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112371
tfarina42834112016-09-22 13:38:2012372 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12374 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112375
mmenkea2dcd3bf2016-08-16 21:49:4112376 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212377 ASSERT_TRUE(response);
12378 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212379 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312380 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212381 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112382
robpercival214763f2016-07-01 23:27:0112383 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112384 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512385 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12386 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312387 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312388 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312389 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112390
[email protected]029c83b62013-01-24 05:28:2012391 LoadTimingInfo load_timing_info;
12392 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12393 TestLoadTimingNotReusedWithPac(load_timing_info,
12394 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112395}
[email protected]631f1322010-04-30 17:59:1112396
bncd16676a2016-07-20 16:23:0112397TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812398 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412399 HttpRequestInfo request;
12400 request.method = "GET";
bncb26024382016-06-29 02:39:4512401 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012402 request.traffic_annotation =
12403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412404
12405 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212406 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312407 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212408 MockRead("\r\n"),
12409 MockRead("hello world"),
12410 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412411 };
12412
12413 StaticSocketDataProvider first_transaction(
12414 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712415 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512416 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612417 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412419
bnc032658ba2016-09-26 18:17:1512420 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412421
bncdf80d44fd2016-07-15 20:27:4112422 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512423 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112424 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412425
bnc42331402016-07-25 13:36:1512426 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112427 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412428 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112429 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412430 };
12431
rch8e6c6c42015-05-01 14:05:1312432 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12433 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712434 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412435
[email protected]83039bb2011-12-09 18:43:5512436 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412437
danakj1fd259a02016-04-16 03:17:0912438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412439
bnc87dcefc2017-05-25 12:47:5812440 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912441 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412442
tfarina42834112016-09-22 13:38:2012443 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12445 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412446
12447 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212448 ASSERT_TRUE(response);
12449 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412450 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12451
12452 std::string response_data;
robpercival214763f2016-07-01 23:27:0112453 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412454 EXPECT_EQ("hello world", response_data);
12455
12456 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512457 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012458 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412459 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712460 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212461 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812462
bnc87dcefc2017-05-25 12:47:5812463 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912464 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412465
tfarina42834112016-09-22 13:38:2012466 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12468 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412469
12470 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212471 ASSERT_TRUE(response);
12472 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212473 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312474 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212475 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412476
robpercival214763f2016-07-01 23:27:0112477 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412478 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212479}
12480
[email protected]044de0642010-06-17 10:42:1512481// GenerateAuthToken is a mighty big test.
12482// It tests all permutation of GenerateAuthToken behavior:
12483// - Synchronous and Asynchronous completion.
12484// - OK or error on completion.
12485// - Direct connection, non-authenticating proxy, and authenticating proxy.
12486// - HTTP or HTTPS backend (to include proxy tunneling).
12487// - Non-authenticating and authenticating backend.
12488//
[email protected]fe3b7dc2012-02-03 19:52:0912489// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512490// problems generating an auth token for an authenticating proxy, we don't
12491// need to test all permutations of the backend server).
12492//
12493// The test proceeds by going over each of the configuration cases, and
12494// potentially running up to three rounds in each of the tests. The TestConfig
12495// specifies both the configuration for the test as well as the expectations
12496// for the results.
bncd16676a2016-07-20 16:23:0112497TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012498 static const char kServer[] = "http://www.example.com";
12499 static const char kSecureServer[] = "https://www.example.com";
12500 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512501
12502 enum AuthTiming {
12503 AUTH_NONE,
12504 AUTH_SYNC,
12505 AUTH_ASYNC,
12506 };
12507
12508 const MockWrite kGet(
12509 "GET / HTTP/1.1\r\n"
12510 "Host: www.example.com\r\n"
12511 "Connection: keep-alive\r\n\r\n");
12512 const MockWrite kGetProxy(
12513 "GET http://www.example.com/ HTTP/1.1\r\n"
12514 "Host: www.example.com\r\n"
12515 "Proxy-Connection: keep-alive\r\n\r\n");
12516 const MockWrite kGetAuth(
12517 "GET / HTTP/1.1\r\n"
12518 "Host: www.example.com\r\n"
12519 "Connection: keep-alive\r\n"
12520 "Authorization: auth_token\r\n\r\n");
12521 const MockWrite kGetProxyAuth(
12522 "GET http://www.example.com/ HTTP/1.1\r\n"
12523 "Host: www.example.com\r\n"
12524 "Proxy-Connection: keep-alive\r\n"
12525 "Proxy-Authorization: auth_token\r\n\r\n");
12526 const MockWrite kGetAuthThroughProxy(
12527 "GET http://www.example.com/ HTTP/1.1\r\n"
12528 "Host: www.example.com\r\n"
12529 "Proxy-Connection: keep-alive\r\n"
12530 "Authorization: auth_token\r\n\r\n");
12531 const MockWrite kGetAuthWithProxyAuth(
12532 "GET http://www.example.com/ HTTP/1.1\r\n"
12533 "Host: www.example.com\r\n"
12534 "Proxy-Connection: keep-alive\r\n"
12535 "Proxy-Authorization: auth_token\r\n"
12536 "Authorization: auth_token\r\n\r\n");
12537 const MockWrite kConnect(
12538 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712539 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512540 "Proxy-Connection: keep-alive\r\n\r\n");
12541 const MockWrite kConnectProxyAuth(
12542 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712543 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512544 "Proxy-Connection: keep-alive\r\n"
12545 "Proxy-Authorization: auth_token\r\n\r\n");
12546
12547 const MockRead kSuccess(
12548 "HTTP/1.1 200 OK\r\n"
12549 "Content-Type: text/html; charset=iso-8859-1\r\n"
12550 "Content-Length: 3\r\n\r\n"
12551 "Yes");
12552 const MockRead kFailure(
12553 "Should not be called.");
12554 const MockRead kServerChallenge(
12555 "HTTP/1.1 401 Unauthorized\r\n"
12556 "WWW-Authenticate: Mock realm=server\r\n"
12557 "Content-Type: text/html; charset=iso-8859-1\r\n"
12558 "Content-Length: 14\r\n\r\n"
12559 "Unauthorized\r\n");
12560 const MockRead kProxyChallenge(
12561 "HTTP/1.1 407 Unauthorized\r\n"
12562 "Proxy-Authenticate: Mock realm=proxy\r\n"
12563 "Proxy-Connection: close\r\n"
12564 "Content-Type: text/html; charset=iso-8859-1\r\n"
12565 "Content-Length: 14\r\n\r\n"
12566 "Unauthorized\r\n");
12567 const MockRead kProxyConnected(
12568 "HTTP/1.1 200 Connection Established\r\n\r\n");
12569
12570 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12571 // no constructors, but the C++ compiler on Windows warns about
12572 // unspecified data in compound literals. So, moved to using constructors,
12573 // and TestRound's created with the default constructor should not be used.
12574 struct TestRound {
12575 TestRound()
12576 : expected_rv(ERR_UNEXPECTED),
12577 extra_write(NULL),
12578 extra_read(NULL) {
12579 }
12580 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12581 int expected_rv_arg)
12582 : write(write_arg),
12583 read(read_arg),
12584 expected_rv(expected_rv_arg),
12585 extra_write(NULL),
12586 extra_read(NULL) {
12587 }
12588 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12589 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112590 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512591 : write(write_arg),
12592 read(read_arg),
12593 expected_rv(expected_rv_arg),
12594 extra_write(extra_write_arg),
12595 extra_read(extra_read_arg) {
12596 }
12597 MockWrite write;
12598 MockRead read;
12599 int expected_rv;
12600 const MockWrite* extra_write;
12601 const MockRead* extra_read;
12602 };
12603
12604 static const int kNoSSL = 500;
12605
12606 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112607 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112608 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512609 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112610 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112611 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512612 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112613 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512614 int num_auth_rounds;
12615 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612616 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512617 } test_configs[] = {
asankac93076192016-10-03 15:46:0212618 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112619 {__LINE__,
12620 nullptr,
asankac93076192016-10-03 15:46:0212621 AUTH_NONE,
12622 OK,
12623 kServer,
12624 AUTH_NONE,
12625 OK,
12626 1,
12627 kNoSSL,
12628 {TestRound(kGet, kSuccess, OK)}},
12629 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112630 {__LINE__,
12631 nullptr,
asankac93076192016-10-03 15:46:0212632 AUTH_NONE,
12633 OK,
12634 kServer,
12635 AUTH_SYNC,
12636 OK,
12637 2,
12638 kNoSSL,
12639 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512640 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112641 {__LINE__,
12642 nullptr,
asankac93076192016-10-03 15:46:0212643 AUTH_NONE,
12644 OK,
12645 kServer,
12646 AUTH_SYNC,
12647 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612648 3,
12649 kNoSSL,
12650 {TestRound(kGet, kServerChallenge, OK),
12651 TestRound(kGet, kServerChallenge, OK),
12652 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112653 {__LINE__,
12654 nullptr,
asankae2257db2016-10-11 22:03:1612655 AUTH_NONE,
12656 OK,
12657 kServer,
12658 AUTH_SYNC,
12659 ERR_UNSUPPORTED_AUTH_SCHEME,
12660 2,
12661 kNoSSL,
12662 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112663 {__LINE__,
12664 nullptr,
asankae2257db2016-10-11 22:03:1612665 AUTH_NONE,
12666 OK,
12667 kServer,
12668 AUTH_SYNC,
12669 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12670 2,
12671 kNoSSL,
12672 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112673 {__LINE__,
12674 kProxy,
asankae2257db2016-10-11 22:03:1612675 AUTH_SYNC,
12676 ERR_FAILED,
12677 kServer,
12678 AUTH_NONE,
12679 OK,
12680 2,
12681 kNoSSL,
12682 {TestRound(kGetProxy, kProxyChallenge, OK),
12683 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112684 {__LINE__,
12685 kProxy,
asankae2257db2016-10-11 22:03:1612686 AUTH_ASYNC,
12687 ERR_FAILED,
12688 kServer,
12689 AUTH_NONE,
12690 OK,
12691 2,
12692 kNoSSL,
12693 {TestRound(kGetProxy, kProxyChallenge, OK),
12694 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112695 {__LINE__,
12696 nullptr,
asankae2257db2016-10-11 22:03:1612697 AUTH_NONE,
12698 OK,
12699 kServer,
12700 AUTH_SYNC,
12701 ERR_FAILED,
asankac93076192016-10-03 15:46:0212702 2,
12703 kNoSSL,
12704 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612705 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112706 {__LINE__,
12707 nullptr,
asankae2257db2016-10-11 22:03:1612708 AUTH_NONE,
12709 OK,
12710 kServer,
12711 AUTH_ASYNC,
12712 ERR_FAILED,
12713 2,
12714 kNoSSL,
12715 {TestRound(kGet, kServerChallenge, OK),
12716 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112717 {__LINE__,
12718 nullptr,
asankac93076192016-10-03 15:46:0212719 AUTH_NONE,
12720 OK,
12721 kServer,
12722 AUTH_ASYNC,
12723 OK,
12724 2,
12725 kNoSSL,
12726 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512727 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112728 {__LINE__,
12729 nullptr,
asankac93076192016-10-03 15:46:0212730 AUTH_NONE,
12731 OK,
12732 kServer,
12733 AUTH_ASYNC,
12734 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612735 3,
asankac93076192016-10-03 15:46:0212736 kNoSSL,
12737 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612738 // The second round uses a HttpAuthHandlerMock that always succeeds.
12739 TestRound(kGet, kServerChallenge, OK),
12740 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212741 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112742 {__LINE__,
12743 kProxy,
asankac93076192016-10-03 15:46:0212744 AUTH_NONE,
12745 OK,
12746 kServer,
12747 AUTH_NONE,
12748 OK,
12749 1,
12750 kNoSSL,
12751 {TestRound(kGetProxy, kSuccess, OK)}},
12752 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112753 {__LINE__,
12754 kProxy,
asankac93076192016-10-03 15:46:0212755 AUTH_NONE,
12756 OK,
12757 kServer,
12758 AUTH_SYNC,
12759 OK,
12760 2,
12761 kNoSSL,
12762 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512763 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112764 {__LINE__,
12765 kProxy,
asankac93076192016-10-03 15:46:0212766 AUTH_NONE,
12767 OK,
12768 kServer,
12769 AUTH_SYNC,
12770 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612771 3,
asankac93076192016-10-03 15:46:0212772 kNoSSL,
12773 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612774 TestRound(kGetProxy, kServerChallenge, OK),
12775 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112776 {__LINE__,
12777 kProxy,
asankac93076192016-10-03 15:46:0212778 AUTH_NONE,
12779 OK,
12780 kServer,
12781 AUTH_ASYNC,
12782 OK,
12783 2,
12784 kNoSSL,
12785 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512786 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112787 {__LINE__,
12788 kProxy,
asankac93076192016-10-03 15:46:0212789 AUTH_NONE,
12790 OK,
12791 kServer,
12792 AUTH_ASYNC,
12793 ERR_INVALID_AUTH_CREDENTIALS,
12794 2,
12795 kNoSSL,
12796 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612797 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212798 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112799 {__LINE__,
12800 kProxy,
asankac93076192016-10-03 15:46:0212801 AUTH_SYNC,
12802 OK,
12803 kServer,
12804 AUTH_NONE,
12805 OK,
12806 2,
12807 kNoSSL,
12808 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512809 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112810 {__LINE__,
12811 kProxy,
asankac93076192016-10-03 15:46:0212812 AUTH_SYNC,
12813 ERR_INVALID_AUTH_CREDENTIALS,
12814 kServer,
12815 AUTH_NONE,
12816 OK,
12817 2,
12818 kNoSSL,
12819 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612820 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112821 {__LINE__,
12822 kProxy,
asankac93076192016-10-03 15:46:0212823 AUTH_ASYNC,
12824 OK,
12825 kServer,
12826 AUTH_NONE,
12827 OK,
12828 2,
12829 kNoSSL,
12830 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512831 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112832 {__LINE__,
12833 kProxy,
asankac93076192016-10-03 15:46:0212834 AUTH_ASYNC,
12835 ERR_INVALID_AUTH_CREDENTIALS,
12836 kServer,
12837 AUTH_NONE,
12838 OK,
12839 2,
12840 kNoSSL,
12841 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612842 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112843 {__LINE__,
12844 kProxy,
12845 AUTH_ASYNC,
12846 ERR_INVALID_AUTH_CREDENTIALS,
12847 kServer,
12848 AUTH_NONE,
12849 OK,
12850 3,
12851 kNoSSL,
12852 {TestRound(kGetProxy, kProxyChallenge, OK),
12853 TestRound(kGetProxy, kProxyChallenge, OK),
12854 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212855 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112856 {__LINE__,
12857 kProxy,
asankac93076192016-10-03 15:46:0212858 AUTH_SYNC,
12859 OK,
12860 kServer,
12861 AUTH_SYNC,
12862 OK,
12863 3,
12864 kNoSSL,
12865 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512866 TestRound(kGetProxyAuth, kServerChallenge, OK),
12867 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112868 {__LINE__,
12869 kProxy,
asankac93076192016-10-03 15:46:0212870 AUTH_SYNC,
12871 OK,
12872 kServer,
12873 AUTH_SYNC,
12874 ERR_INVALID_AUTH_CREDENTIALS,
12875 3,
12876 kNoSSL,
12877 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512878 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612879 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112880 {__LINE__,
12881 kProxy,
asankac93076192016-10-03 15:46:0212882 AUTH_ASYNC,
12883 OK,
12884 kServer,
12885 AUTH_SYNC,
12886 OK,
12887 3,
12888 kNoSSL,
12889 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512890 TestRound(kGetProxyAuth, kServerChallenge, OK),
12891 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112892 {__LINE__,
12893 kProxy,
asankac93076192016-10-03 15:46:0212894 AUTH_ASYNC,
12895 OK,
12896 kServer,
12897 AUTH_SYNC,
12898 ERR_INVALID_AUTH_CREDENTIALS,
12899 3,
12900 kNoSSL,
12901 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512902 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612903 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112904 {__LINE__,
12905 kProxy,
asankac93076192016-10-03 15:46:0212906 AUTH_SYNC,
12907 OK,
12908 kServer,
12909 AUTH_ASYNC,
12910 OK,
12911 3,
12912 kNoSSL,
12913 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512914 TestRound(kGetProxyAuth, kServerChallenge, OK),
12915 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112916 {__LINE__,
12917 kProxy,
12918 AUTH_SYNC,
12919 ERR_INVALID_AUTH_CREDENTIALS,
12920 kServer,
12921 AUTH_ASYNC,
12922 OK,
12923 4,
12924 kNoSSL,
12925 {TestRound(kGetProxy, kProxyChallenge, OK),
12926 TestRound(kGetProxy, kProxyChallenge, OK),
12927 TestRound(kGetProxyAuth, kServerChallenge, OK),
12928 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12929 {__LINE__,
12930 kProxy,
asankac93076192016-10-03 15:46:0212931 AUTH_SYNC,
12932 OK,
12933 kServer,
12934 AUTH_ASYNC,
12935 ERR_INVALID_AUTH_CREDENTIALS,
12936 3,
12937 kNoSSL,
12938 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512939 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612940 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112941 {__LINE__,
12942 kProxy,
asankac93076192016-10-03 15:46:0212943 AUTH_ASYNC,
12944 OK,
12945 kServer,
12946 AUTH_ASYNC,
12947 OK,
12948 3,
12949 kNoSSL,
12950 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512951 TestRound(kGetProxyAuth, kServerChallenge, OK),
12952 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112953 {__LINE__,
12954 kProxy,
asankac93076192016-10-03 15:46:0212955 AUTH_ASYNC,
12956 OK,
12957 kServer,
12958 AUTH_ASYNC,
12959 ERR_INVALID_AUTH_CREDENTIALS,
12960 3,
12961 kNoSSL,
12962 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512963 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612964 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112965 {__LINE__,
12966 kProxy,
12967 AUTH_ASYNC,
12968 ERR_INVALID_AUTH_CREDENTIALS,
12969 kServer,
12970 AUTH_ASYNC,
12971 ERR_INVALID_AUTH_CREDENTIALS,
12972 4,
12973 kNoSSL,
12974 {TestRound(kGetProxy, kProxyChallenge, OK),
12975 TestRound(kGetProxy, kProxyChallenge, OK),
12976 TestRound(kGetProxyAuth, kServerChallenge, OK),
12977 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212978 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112979 {__LINE__,
12980 nullptr,
asankac93076192016-10-03 15:46:0212981 AUTH_NONE,
12982 OK,
12983 kSecureServer,
12984 AUTH_NONE,
12985 OK,
12986 1,
12987 0,
12988 {TestRound(kGet, kSuccess, OK)}},
12989 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112990 {__LINE__,
12991 nullptr,
asankac93076192016-10-03 15:46:0212992 AUTH_NONE,
12993 OK,
12994 kSecureServer,
12995 AUTH_SYNC,
12996 OK,
12997 2,
12998 0,
12999 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513000 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113001 {__LINE__,
13002 nullptr,
asankac93076192016-10-03 15:46:0213003 AUTH_NONE,
13004 OK,
13005 kSecureServer,
13006 AUTH_SYNC,
13007 ERR_INVALID_AUTH_CREDENTIALS,
13008 2,
13009 0,
asankae2257db2016-10-11 22:03:1613010 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113011 {__LINE__,
13012 nullptr,
asankac93076192016-10-03 15:46:0213013 AUTH_NONE,
13014 OK,
13015 kSecureServer,
13016 AUTH_ASYNC,
13017 OK,
13018 2,
13019 0,
13020 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513021 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113022 {__LINE__,
13023 nullptr,
asankac93076192016-10-03 15:46:0213024 AUTH_NONE,
13025 OK,
13026 kSecureServer,
13027 AUTH_ASYNC,
13028 ERR_INVALID_AUTH_CREDENTIALS,
13029 2,
13030 0,
asankae2257db2016-10-11 22:03:1613031 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213032 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113033 {__LINE__,
13034 kProxy,
asankac93076192016-10-03 15:46:0213035 AUTH_NONE,
13036 OK,
13037 kSecureServer,
13038 AUTH_NONE,
13039 OK,
13040 1,
13041 0,
13042 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13043 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113044 {__LINE__,
13045 kProxy,
asankac93076192016-10-03 15:46:0213046 AUTH_NONE,
13047 OK,
13048 kSecureServer,
13049 AUTH_SYNC,
13050 OK,
13051 2,
13052 0,
13053 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513054 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113055 {__LINE__,
13056 kProxy,
asankac93076192016-10-03 15:46:0213057 AUTH_NONE,
13058 OK,
13059 kSecureServer,
13060 AUTH_SYNC,
13061 ERR_INVALID_AUTH_CREDENTIALS,
13062 2,
13063 0,
13064 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613065 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113066 {__LINE__,
13067 kProxy,
asankac93076192016-10-03 15:46:0213068 AUTH_NONE,
13069 OK,
13070 kSecureServer,
13071 AUTH_ASYNC,
13072 OK,
13073 2,
13074 0,
13075 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513076 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113077 {__LINE__,
13078 kProxy,
asankac93076192016-10-03 15:46:0213079 AUTH_NONE,
13080 OK,
13081 kSecureServer,
13082 AUTH_ASYNC,
13083 ERR_INVALID_AUTH_CREDENTIALS,
13084 2,
13085 0,
13086 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613087 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213088 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113089 {__LINE__,
13090 kProxy,
asankac93076192016-10-03 15:46:0213091 AUTH_SYNC,
13092 OK,
13093 kSecureServer,
13094 AUTH_NONE,
13095 OK,
13096 2,
13097 1,
13098 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513099 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113100 {__LINE__,
13101 kProxy,
asankac93076192016-10-03 15:46:0213102 AUTH_SYNC,
13103 ERR_INVALID_AUTH_CREDENTIALS,
13104 kSecureServer,
13105 AUTH_NONE,
13106 OK,
13107 2,
13108 kNoSSL,
13109 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613110 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113111 {__LINE__,
13112 kProxy,
asankae2257db2016-10-11 22:03:1613113 AUTH_SYNC,
13114 ERR_UNSUPPORTED_AUTH_SCHEME,
13115 kSecureServer,
13116 AUTH_NONE,
13117 OK,
13118 2,
13119 kNoSSL,
13120 {TestRound(kConnect, kProxyChallenge, OK),
13121 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113122 {__LINE__,
13123 kProxy,
asankae2257db2016-10-11 22:03:1613124 AUTH_SYNC,
13125 ERR_UNEXPECTED,
13126 kSecureServer,
13127 AUTH_NONE,
13128 OK,
13129 2,
13130 kNoSSL,
13131 {TestRound(kConnect, kProxyChallenge, OK),
13132 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113133 {__LINE__,
13134 kProxy,
asankac93076192016-10-03 15:46:0213135 AUTH_ASYNC,
13136 OK,
13137 kSecureServer,
13138 AUTH_NONE,
13139 OK,
13140 2,
13141 1,
13142 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513143 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113144 {__LINE__,
13145 kProxy,
asankac93076192016-10-03 15:46:0213146 AUTH_ASYNC,
13147 ERR_INVALID_AUTH_CREDENTIALS,
13148 kSecureServer,
13149 AUTH_NONE,
13150 OK,
13151 2,
13152 kNoSSL,
13153 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613154 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213155 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113156 {__LINE__,
13157 kProxy,
asankac93076192016-10-03 15:46:0213158 AUTH_SYNC,
13159 OK,
13160 kSecureServer,
13161 AUTH_SYNC,
13162 OK,
13163 3,
13164 1,
13165 {TestRound(kConnect, kProxyChallenge, OK),
13166 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13167 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513168 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113169 {__LINE__,
13170 kProxy,
asankac93076192016-10-03 15:46:0213171 AUTH_SYNC,
13172 OK,
13173 kSecureServer,
13174 AUTH_SYNC,
13175 ERR_INVALID_AUTH_CREDENTIALS,
13176 3,
13177 1,
13178 {TestRound(kConnect, kProxyChallenge, OK),
13179 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13180 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613181 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113182 {__LINE__,
13183 kProxy,
asankac93076192016-10-03 15:46:0213184 AUTH_ASYNC,
13185 OK,
13186 kSecureServer,
13187 AUTH_SYNC,
13188 OK,
13189 3,
13190 1,
13191 {TestRound(kConnect, kProxyChallenge, OK),
13192 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13193 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513194 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113195 {__LINE__,
13196 kProxy,
asankac93076192016-10-03 15:46:0213197 AUTH_ASYNC,
13198 OK,
13199 kSecureServer,
13200 AUTH_SYNC,
13201 ERR_INVALID_AUTH_CREDENTIALS,
13202 3,
13203 1,
13204 {TestRound(kConnect, kProxyChallenge, OK),
13205 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13206 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613207 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113208 {__LINE__,
13209 kProxy,
asankac93076192016-10-03 15:46:0213210 AUTH_SYNC,
13211 OK,
13212 kSecureServer,
13213 AUTH_ASYNC,
13214 OK,
13215 3,
13216 1,
13217 {TestRound(kConnect, kProxyChallenge, OK),
13218 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13219 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513220 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113221 {__LINE__,
13222 kProxy,
asankac93076192016-10-03 15:46:0213223 AUTH_SYNC,
13224 OK,
13225 kSecureServer,
13226 AUTH_ASYNC,
13227 ERR_INVALID_AUTH_CREDENTIALS,
13228 3,
13229 1,
13230 {TestRound(kConnect, kProxyChallenge, OK),
13231 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13232 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613233 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113234 {__LINE__,
13235 kProxy,
asankac93076192016-10-03 15:46:0213236 AUTH_ASYNC,
13237 OK,
13238 kSecureServer,
13239 AUTH_ASYNC,
13240 OK,
13241 3,
13242 1,
13243 {TestRound(kConnect, kProxyChallenge, OK),
13244 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13245 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513246 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113247 {__LINE__,
13248 kProxy,
asankac93076192016-10-03 15:46:0213249 AUTH_ASYNC,
13250 OK,
13251 kSecureServer,
13252 AUTH_ASYNC,
13253 ERR_INVALID_AUTH_CREDENTIALS,
13254 3,
13255 1,
13256 {TestRound(kConnect, kProxyChallenge, OK),
13257 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13258 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613259 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113260 {__LINE__,
13261 kProxy,
13262 AUTH_ASYNC,
13263 ERR_INVALID_AUTH_CREDENTIALS,
13264 kSecureServer,
13265 AUTH_ASYNC,
13266 ERR_INVALID_AUTH_CREDENTIALS,
13267 4,
13268 2,
13269 {TestRound(kConnect, kProxyChallenge, OK),
13270 TestRound(kConnect, kProxyChallenge, OK),
13271 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13272 &kServerChallenge),
13273 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513274 };
13275
asanka463ca4262016-11-16 02:34:3113276 for (const auto& test_config : test_configs) {
13277 SCOPED_TRACE(::testing::Message() << "Test config at "
13278 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813279 HttpAuthHandlerMock::Factory* auth_factory(
13280 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713281 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913282 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613283
13284 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513285 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113286 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813287 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13288 std::string auth_challenge = "Mock realm=proxy";
13289 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413290 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13291 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813292 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013293 empty_ssl_info, origin,
13294 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813295 auth_handler->SetGenerateExpectation(
13296 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113297 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813298 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13299 }
[email protected]044de0642010-06-17 10:42:1513300 }
13301 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013302 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513303 std::string auth_challenge = "Mock realm=server";
13304 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413305 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13306 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513307 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013308 empty_ssl_info, origin,
13309 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513310 auth_handler->SetGenerateExpectation(
13311 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113312 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813313 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613314
13315 // The second handler always succeeds. It should only be used where there
13316 // are multiple auth sessions for server auth in the same network
13317 // transaction using the same auth scheme.
13318 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913319 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613320 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13321 empty_ssl_info, origin,
13322 NetLogWithSource());
13323 second_handler->SetGenerateExpectation(true, OK);
13324 auth_factory->AddMockHandler(second_handler.release(),
13325 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513326 }
13327 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913328 session_deps_.proxy_resolution_service =
13329 ProxyResolutionService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1513330 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913331 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513332 }
13333
13334 HttpRequestInfo request;
13335 request.method = "GET";
13336 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1013337 request.traffic_annotation =
13338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513339
danakj1fd259a02016-04-16 03:17:0913340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513341
rchcb68dc62015-05-21 04:45:3613342 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13343
13344 std::vector<std::vector<MockRead>> mock_reads(1);
13345 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513346 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213347 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513348 const TestRound& read_write_round = test_config.rounds[round];
13349
13350 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613351 mock_reads.back().push_back(read_write_round.read);
13352 mock_writes.back().push_back(read_write_round.write);
13353
13354 // kProxyChallenge uses Proxy-Connection: close which means that the
13355 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413356 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613357 mock_reads.push_back(std::vector<MockRead>());
13358 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513359 }
13360
rchcb68dc62015-05-21 04:45:3613361 if (read_write_round.extra_read) {
13362 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513363 }
rchcb68dc62015-05-21 04:45:3613364 if (read_write_round.extra_write) {
13365 mock_writes.back().push_back(*read_write_round.extra_write);
13366 }
[email protected]044de0642010-06-17 10:42:1513367
13368 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513369 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713370 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513371 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613372 }
[email protected]044de0642010-06-17 10:42:1513373
danakj1fd259a02016-04-16 03:17:0913374 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613375 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913376 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413377 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813378 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613379 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213380 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613381 }
13382
mmenkecc2298e2015-12-07 18:20:1813383 // Transaction must be created after DataProviders, so it's destroyed before
13384 // they are as well.
13385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13386
rchcb68dc62015-05-21 04:45:3613387 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213388 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613389 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513390 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113391 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513392 int rv;
13393 if (round == 0) {
tfarina42834112016-09-22 13:38:2013394 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513395 } else {
[email protected]49639fa2011-12-20 23:22:4113396 rv = trans.RestartWithAuth(
13397 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513398 }
13399 if (rv == ERR_IO_PENDING)
13400 rv = callback.WaitForResult();
13401
13402 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613403 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013404 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513405 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513406 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13407 continue;
13408 }
13409 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213410 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513411 } else {
wezca1070932016-05-26 20:30:5213412 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613413 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513414 }
13415 }
[email protected]e5ae96a2010-04-14 20:12:4513416 }
13417}
13418
bncd16676a2016-07-20 16:23:0113419TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413420 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413421 HttpAuthHandlerMock::Factory* auth_factory(
13422 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713423 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913424 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713425 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13426 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413427
13428 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13429 auth_handler->set_connection_based(true);
13430 std::string auth_challenge = "Mock realm=server";
13431 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413432 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13433 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913434 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413435 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013436 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813437 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413438
[email protected]c871bce92010-07-15 21:51:1413439 int rv = OK;
13440 const HttpResponseInfo* response = NULL;
13441 HttpRequestInfo request;
13442 request.method = "GET";
13443 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1013444 request.traffic_annotation =
13445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713446
danakj1fd259a02016-04-16 03:17:0913447 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013448
13449 // Use a TCP Socket Pool with only one connection per group. This is used
13450 // to validate that the TCP socket is not released to the pool between
13451 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213452 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813453 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013454 50, // Max sockets for pool
13455 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113456 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13457 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913458 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213459 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813460 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013461
bnc691fda62016-08-12 00:43:1613462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113463 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413464
13465 const MockWrite kGet(
13466 "GET / HTTP/1.1\r\n"
13467 "Host: www.example.com\r\n"
13468 "Connection: keep-alive\r\n\r\n");
13469 const MockWrite kGetAuth(
13470 "GET / HTTP/1.1\r\n"
13471 "Host: www.example.com\r\n"
13472 "Connection: keep-alive\r\n"
13473 "Authorization: auth_token\r\n\r\n");
13474
13475 const MockRead kServerChallenge(
13476 "HTTP/1.1 401 Unauthorized\r\n"
13477 "WWW-Authenticate: Mock realm=server\r\n"
13478 "Content-Type: text/html; charset=iso-8859-1\r\n"
13479 "Content-Length: 14\r\n\r\n"
13480 "Unauthorized\r\n");
13481 const MockRead kSuccess(
13482 "HTTP/1.1 200 OK\r\n"
13483 "Content-Type: text/html; charset=iso-8859-1\r\n"
13484 "Content-Length: 3\r\n\r\n"
13485 "Yes");
13486
13487 MockWrite writes[] = {
13488 // First round
13489 kGet,
13490 // Second round
13491 kGetAuth,
13492 // Third round
13493 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013494 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013495 kGetAuth,
13496 // Competing request
13497 kGet,
[email protected]c871bce92010-07-15 21:51:1413498 };
13499 MockRead reads[] = {
13500 // First round
13501 kServerChallenge,
13502 // Second round
13503 kServerChallenge,
13504 // Third round
[email protected]eca50e122010-09-11 14:03:3013505 kServerChallenge,
13506 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413507 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013508 // Competing response
13509 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413510 };
13511 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13512 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713513 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413514
thestig9d3bb0c2015-01-24 00:49:5113515 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013516
13517 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413518 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013519 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413520 if (rv == ERR_IO_PENDING)
13521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113522 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613523 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213524 ASSERT_TRUE(response);
13525 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813526 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113527 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13528 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413529
[email protected]7ef4cbbb2011-02-06 11:19:1013530 // In between rounds, another request comes in for the same domain.
13531 // It should not be able to grab the TCP socket that trans has already
13532 // claimed.
bnc691fda62016-08-12 00:43:1613533 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113534 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013535 rv = trans_compete.Start(&request, callback_compete.callback(),
13536 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013538 // callback_compete.WaitForResult at this point would stall forever,
13539 // since the HttpNetworkTransaction does not release the request back to
13540 // the pool until after authentication completes.
13541
13542 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413543 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613544 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413545 if (rv == ERR_IO_PENDING)
13546 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113547 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613548 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213549 ASSERT_TRUE(response);
13550 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813551 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113552 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13553 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413554
[email protected]7ef4cbbb2011-02-06 11:19:1013555 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413556 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613557 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413558 if (rv == ERR_IO_PENDING)
13559 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113560 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613561 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213562 ASSERT_TRUE(response);
13563 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813564 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113565 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13566 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013567
[email protected]7ef4cbbb2011-02-06 11:19:1013568 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013569 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613570 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013571 if (rv == ERR_IO_PENDING)
13572 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113573 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613574 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213575 ASSERT_TRUE(response);
13576 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813577 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013578
asanka463ca4262016-11-16 02:34:3113579 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13580 // auth handler should transition to a DONE state in concert with the remote
13581 // server. But that's not something we can test here with a mock handler.
13582 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13583 auth_handler->state());
13584
[email protected]7ef4cbbb2011-02-06 11:19:1013585 // Read the body since the fourth round was successful. This will also
13586 // release the socket back to the pool.
13587 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613588 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013589 if (rv == ERR_IO_PENDING)
13590 rv = callback.WaitForResult();
13591 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613592 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013593 EXPECT_EQ(0, rv);
13594 // There are still 0 idle sockets, since the trans_compete transaction
13595 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813596 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013597
13598 // The competing request can now finish. Wait for the headers and then
13599 // read the body.
13600 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113601 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613602 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013603 if (rv == ERR_IO_PENDING)
13604 rv = callback.WaitForResult();
13605 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613606 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013607 EXPECT_EQ(0, rv);
13608
13609 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813610 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413611}
13612
[email protected]65041fa2010-05-21 06:56:5313613// This tests the case that a request is issued via http instead of spdy after
13614// npn is negotiated.
bncd16676a2016-07-20 16:23:0113615TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313616 HttpRequestInfo request;
13617 request.method = "GET";
bncce36dca22015-04-21 22:11:2313618 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013619 request.traffic_annotation =
13620 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313621
13622 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313623 MockWrite(
13624 "GET / HTTP/1.1\r\n"
13625 "Host: www.example.org\r\n"
13626 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313627 };
13628
13629 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213630 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313631 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213632 MockRead("\r\n"),
13633 MockRead("hello world"),
13634 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313635 };
13636
[email protected]8ddf8322012-02-23 18:08:0613637 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613638 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313639
[email protected]bb88e1d32013-05-03 23:11:0713640 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313641
13642 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13643 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713644 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313645
[email protected]49639fa2011-12-20 23:22:4113646 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313647
danakj1fd259a02016-04-16 03:17:0913648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313650
tfarina42834112016-09-22 13:38:2013651 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313652
robpercival214763f2016-07-01 23:27:0113653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13654 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313655
bnc691fda62016-08-12 00:43:1613656 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213657 ASSERT_TRUE(response);
13658 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313659 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13660
13661 std::string response_data;
bnc691fda62016-08-12 00:43:1613662 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313663 EXPECT_EQ("hello world", response_data);
13664
13665 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213666 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313667}
[email protected]26ef6582010-06-24 02:30:4713668
bnc55ff9da2015-08-19 18:42:3513669// Simulate the SSL handshake completing with an NPN negotiation followed by an
13670// immediate server closing of the socket.
13671// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113672TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713673 HttpRequestInfo request;
13674 request.method = "GET";
bncce36dca22015-04-21 22:11:2313675 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013676 request.traffic_annotation =
13677 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713678
[email protected]8ddf8322012-02-23 18:08:0613679 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613680 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713682
bncdf80d44fd2016-07-15 20:27:4113683 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913684 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4113685 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713686
13687 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613688 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713689 };
13690
rch8e6c6c42015-05-01 14:05:1313691 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13692 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713693 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713694
[email protected]49639fa2011-12-20 23:22:4113695 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713696
danakj1fd259a02016-04-16 03:17:0913697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613698 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713699
tfarina42834112016-09-22 13:38:2013700 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13702 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713703}
[email protected]65d34382010-07-01 18:12:2613704
[email protected]795cbf82013-07-22 09:37:2713705// A subclass of HttpAuthHandlerMock that records the request URL when
13706// it gets it. This is needed since the auth handler may get destroyed
13707// before we get a chance to query it.
13708class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13709 public:
13710 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13711
Chris Watkins7a41d3552017-12-01 02:13:2713712 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713713
13714 protected:
dchengb03027d2014-10-21 12:00:2013715 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13716 const HttpRequestInfo* request,
13717 const CompletionCallback& callback,
13718 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713719 *url_ = request->url;
13720 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13721 credentials, request, callback, auth_token);
13722 }
13723
13724 private:
13725 GURL* url_;
13726};
13727
[email protected]8e6441ca2010-08-19 05:56:3813728// Test that if we cancel the transaction as the connection is completing, that
13729// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113730TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813731 // Setup everything about the connection to complete synchronously, so that
13732 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13733 // for is the callback from the HttpStreamRequest.
13734 // Then cancel the transaction.
13735 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613736 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813737 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613738 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13739 MockRead(SYNCHRONOUS, "hello world"),
13740 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813741 };
13742
[email protected]8e6441ca2010-08-19 05:56:3813743 HttpRequestInfo request;
13744 request.method = "GET";
bncce36dca22015-04-21 22:11:2313745 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013746 request.traffic_annotation =
13747 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813748
[email protected]bb88e1d32013-05-03 23:11:0713749 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813751 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913752 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713753
[email protected]8e6441ca2010-08-19 05:56:3813754 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13755 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713756 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813757
[email protected]49639fa2011-12-20 23:22:4113758 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813759
vishal.b62985ca92015-04-17 08:45:5113760 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113761 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813763 trans.reset(); // Cancel the transaction here.
13764
fdoray92e35a72016-06-10 15:54:5513765 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013766}
13767
[email protected]ecab6e052014-05-16 14:58:1213768// Test that if a transaction is cancelled after receiving the headers, the
13769// stream is drained properly and added back to the socket pool. The main
13770// purpose of this test is to make sure that an HttpStreamParser can be read
13771// from after the HttpNetworkTransaction and the objects it owns have been
13772// deleted.
13773// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113774TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213775 MockRead data_reads[] = {
13776 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13777 MockRead(ASYNC, "Content-Length: 2\r\n"),
13778 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13779 MockRead(ASYNC, "1"),
13780 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13781 // HttpNetworkTransaction has been deleted.
13782 MockRead(ASYNC, "2"),
13783 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13784 };
13785 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13786 session_deps_.socket_factory->AddSocketDataProvider(&data);
13787
danakj1fd259a02016-04-16 03:17:0913788 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213789
13790 {
13791 HttpRequestInfo request;
13792 request.method = "GET";
bncce36dca22015-04-21 22:11:2313793 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013794 request.traffic_annotation =
13795 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213796
dcheng48459ac22014-08-26 00:46:4113797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213798 TestCompletionCallback callback;
13799
tfarina42834112016-09-22 13:38:2013800 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213802 callback.WaitForResult();
13803
13804 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213805 ASSERT_TRUE(response);
13806 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213807 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13808
13809 // The transaction and HttpRequestInfo are deleted.
13810 }
13811
13812 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513813 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213814
13815 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113816 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213817}
13818
[email protected]76a505b2010-08-25 06:23:0013819// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113820TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913821 session_deps_.proxy_resolution_service =
13822 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113823 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713824 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013826
[email protected]76a505b2010-08-25 06:23:0013827 HttpRequestInfo request;
13828 request.method = "GET";
bncce36dca22015-04-21 22:11:2313829 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013830 request.traffic_annotation =
13831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013832
13833 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313834 MockWrite(
13835 "GET http://www.example.org/ HTTP/1.1\r\n"
13836 "Host: www.example.org\r\n"
13837 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013838 };
13839
13840 MockRead data_reads1[] = {
13841 MockRead("HTTP/1.1 200 OK\r\n"),
13842 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13843 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613844 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013845 };
13846
13847 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13848 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713849 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013850
[email protected]49639fa2011-12-20 23:22:4113851 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013852
bnc691fda62016-08-12 00:43:1613853 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913854 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613855 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913856 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13857 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013858
bnc691fda62016-08-12 00:43:1613859 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013861
13862 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113863 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013864
bnc691fda62016-08-12 00:43:1613865 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213866 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013867
13868 EXPECT_TRUE(response->headers->IsKeepAlive());
13869 EXPECT_EQ(200, response->headers->response_code());
13870 EXPECT_EQ(100, response->headers->GetContentLength());
13871 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713872 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13873 HostPortPair::FromString("myproxy:70")),
13874 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913875 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13876 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13877 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013878 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013879
13880 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613881 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013882 TestLoadTimingNotReusedWithPac(load_timing_info,
13883 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013884}
13885
13886// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113887TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913888 session_deps_.proxy_resolution_service =
13889 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113890 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713891 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013893
[email protected]76a505b2010-08-25 06:23:0013894 HttpRequestInfo request;
13895 request.method = "GET";
bncce36dca22015-04-21 22:11:2313896 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013897 request.traffic_annotation =
13898 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013899
13900 // Since we have proxy, should try to establish tunnel.
13901 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713902 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13903 "Host: www.example.org:443\r\n"
13904 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013905
rsleevidb16bb02015-11-12 23:47:1713906 MockWrite("GET / HTTP/1.1\r\n"
13907 "Host: www.example.org\r\n"
13908 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013909 };
13910
13911 MockRead data_reads1[] = {
13912 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13913
13914 MockRead("HTTP/1.1 200 OK\r\n"),
13915 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13916 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613917 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013918 };
13919
13920 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13921 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713922 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613923 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713924 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013925
[email protected]49639fa2011-12-20 23:22:4113926 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013927
bnc691fda62016-08-12 00:43:1613928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913929 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613930 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913931 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13932 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013933
bnc691fda62016-08-12 00:43:1613934 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113935 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013936
13937 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113938 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613939 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013940 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013941 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013942 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13943 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013944 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013945 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013946 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13947 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013948
bnc691fda62016-08-12 00:43:1613949 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213950 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013951
13952 EXPECT_TRUE(response->headers->IsKeepAlive());
13953 EXPECT_EQ(200, response->headers->response_code());
13954 EXPECT_EQ(100, response->headers->GetContentLength());
13955 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13956 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713957 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13958 HostPortPair::FromString("myproxy:70")),
13959 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913960 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13961 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13962 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013963
13964 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613965 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013966 TestLoadTimingNotReusedWithPac(load_timing_info,
13967 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013968}
13969
rsleevidb16bb02015-11-12 23:47:1713970// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13971// literal host.
bncd16676a2016-07-20 16:23:0113972TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913973 session_deps_.proxy_resolution_service =
13974 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
rsleevidb16bb02015-11-12 23:47:1713975 BoundTestNetLog log;
13976 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713978
13979 HttpRequestInfo request;
13980 request.method = "GET";
13981 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1013982 request.traffic_annotation =
13983 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713984
13985 // Since we have proxy, should try to establish tunnel.
13986 MockWrite data_writes1[] = {
13987 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13988 "Host: [::1]:443\r\n"
13989 "Proxy-Connection: keep-alive\r\n\r\n"),
13990
13991 MockWrite("GET / HTTP/1.1\r\n"
13992 "Host: [::1]\r\n"
13993 "Connection: keep-alive\r\n\r\n"),
13994 };
13995
13996 MockRead data_reads1[] = {
13997 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13998
13999 MockRead("HTTP/1.1 200 OK\r\n"),
14000 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14001 MockRead("Content-Length: 100\r\n\r\n"),
14002 MockRead(SYNCHRONOUS, OK),
14003 };
14004
14005 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14006 data_writes1, arraysize(data_writes1));
14007 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14008 SSLSocketDataProvider ssl(ASYNC, OK);
14009 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14010
14011 TestCompletionCallback callback1;
14012
bnc691fda62016-08-12 00:43:1614013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714014
bnc691fda62016-08-12 00:43:1614015 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714017
14018 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114019 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714020 TestNetLogEntry::List entries;
14021 log.GetEntries(&entries);
14022 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014023 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14024 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714025 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014026 entries, pos,
14027 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14028 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714029
bnc691fda62016-08-12 00:43:1614030 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214031 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714032
14033 EXPECT_TRUE(response->headers->IsKeepAlive());
14034 EXPECT_EQ(200, response->headers->response_code());
14035 EXPECT_EQ(100, response->headers->GetContentLength());
14036 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14037 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714038 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14039 HostPortPair::FromString("myproxy:70")),
14040 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714041
14042 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614043 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714044 TestLoadTimingNotReusedWithPac(load_timing_info,
14045 CONNECT_TIMING_HAS_SSL_TIMES);
14046}
14047
[email protected]76a505b2010-08-25 06:23:0014048// Test a basic HTTPS GET request through a proxy, but the server hangs up
14049// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114050TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Lily Houghton8c2f97d2018-01-22 05:06:5914051 session_deps_.proxy_resolution_service =
14052 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5114053 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714054 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014056
[email protected]76a505b2010-08-25 06:23:0014057 HttpRequestInfo request;
14058 request.method = "GET";
bncce36dca22015-04-21 22:11:2314059 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014060 request.traffic_annotation =
14061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014062
14063 // Since we have proxy, should try to establish tunnel.
14064 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714065 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14066 "Host: www.example.org:443\r\n"
14067 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014068
rsleevidb16bb02015-11-12 23:47:1714069 MockWrite("GET / HTTP/1.1\r\n"
14070 "Host: www.example.org\r\n"
14071 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014072 };
14073
14074 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014075 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614076 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014077 };
14078
14079 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
14080 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0714081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614082 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714083 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014084
[email protected]49639fa2011-12-20 23:22:4114085 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014086
bnc691fda62016-08-12 00:43:1614087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014088
bnc691fda62016-08-12 00:43:1614089 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014091
14092 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114093 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614094 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014095 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014096 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014097 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14098 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014099 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014100 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014101 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14102 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014103}
14104
[email protected]749eefa82010-09-13 22:14:0314105// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114106TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4114107 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914108 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114109 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314110
bnc42331402016-07-25 13:36:1514111 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114112 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314113 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114114 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314115 };
14116
rch8e6c6c42015-05-01 14:05:1314117 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
14118 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714119 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314120
[email protected]8ddf8322012-02-23 18:08:0614121 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614122 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714123 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314124
danakj1fd259a02016-04-16 03:17:0914125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314126
14127 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314128 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014129 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414130 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714131 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214132 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314133
14134 HttpRequestInfo request;
14135 request.method = "GET";
bncce36dca22015-04-21 22:11:2314136 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014137 request.traffic_annotation =
14138 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314139
14140 // This is the important line that marks this as a preconnect.
14141 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
14142
bnc691fda62016-08-12 00:43:1614143 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314144
[email protected]41d64e82013-07-03 22:44:2614145 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014146 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14148 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314149}
14150
[email protected]73b8dd222010-11-11 19:55:2414151// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614152// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214153void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714154 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914155 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714156 request_info.url = GURL("https://www.example.com/");
14157 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914158 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014159 request_info.traffic_annotation =
14160 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714161
[email protected]8ddf8322012-02-23 18:08:0614162 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914163 MockWrite data_writes[] = {
14164 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414165 };
ttuttle859dc7a2015-04-23 19:42:2914166 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0714167 session_deps_.socket_factory->AddSocketDataProvider(&data);
14168 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414169
danakj1fd259a02016-04-16 03:17:0914170 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614171 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414172
[email protected]49639fa2011-12-20 23:22:4114173 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014174 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914175 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414176 rv = callback.WaitForResult();
14177 ASSERT_EQ(error, rv);
14178}
14179
bncd16676a2016-07-20 16:23:0114180TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414181 // Just check a grab bag of cert errors.
14182 static const int kErrors[] = {
14183 ERR_CERT_COMMON_NAME_INVALID,
14184 ERR_CERT_AUTHORITY_INVALID,
14185 ERR_CERT_DATE_INVALID,
14186 };
14187 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614188 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14189 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414190 }
14191}
14192
[email protected]bd0b6772011-01-11 19:59:3014193// Ensure that a client certificate is removed from the SSL client auth
14194// cache when:
14195// 1) No proxy is involved.
14196// 2) TLS False Start is disabled.
14197// 3) The initial TLS handshake requests a client certificate.
14198// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114199TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914200 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714201 request_info.url = GURL("https://www.example.com/");
14202 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914203 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014204 request_info.traffic_annotation =
14205 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714206
[email protected]bd0b6772011-01-11 19:59:3014207 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114208 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014209
14210 // [ssl_]data1 contains the data for the first SSL handshake. When a
14211 // CertificateRequest is received for the first time, the handshake will
14212 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914213 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014214 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914216 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714217 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014218
14219 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14220 // False Start is not being used, the result of the SSL handshake will be
14221 // returned as part of the SSLClientSocket::Connect() call. This test
14222 // matches the result of a server sending a handshake_failure alert,
14223 // rather than a Finished message, because it requires a client
14224 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914225 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014226 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914228 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714229 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014230
14231 // [ssl_]data3 contains the data for the third SSL handshake. When a
14232 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214233 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14234 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014235 // of the HttpNetworkTransaction. Because this test failure is due to
14236 // requiring a client certificate, this fallback handshake should also
14237 // fail.
ttuttle859dc7a2015-04-23 19:42:2914238 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014239 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914241 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714242 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014243
[email protected]80c75f682012-05-26 16:22:1714244 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14245 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214246 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14247 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714248 // of the HttpNetworkTransaction. Because this test failure is due to
14249 // requiring a client certificate, this fallback handshake should also
14250 // fail.
ttuttle859dc7a2015-04-23 19:42:2914251 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714252 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714253 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914254 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714255 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714256
danakj1fd259a02016-04-16 03:17:0914257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614258 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014259
[email protected]bd0b6772011-01-11 19:59:3014260 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114261 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014262 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114263 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014264
14265 // Complete the SSL handshake, which should abort due to requiring a
14266 // client certificate.
14267 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114268 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014269
14270 // Indicate that no certificate should be supplied. From the perspective
14271 // of SSLClientCertCache, NULL is just as meaningful as a real
14272 // certificate, so this is the same as supply a
14273 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614274 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114275 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014276
14277 // Ensure the certificate was added to the client auth cache before
14278 // allowing the connection to continue restarting.
14279 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414280 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114281 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414282 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214283 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014284
14285 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714286 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14287 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014288 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114289 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014290
14291 // Ensure that the client certificate is removed from the cache on a
14292 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114293 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414294 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014295}
14296
14297// Ensure that a client certificate is removed from the SSL client auth
14298// cache when:
14299// 1) No proxy is involved.
14300// 2) TLS False Start is enabled.
14301// 3) The initial TLS handshake requests a client certificate.
14302// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114303TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914304 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714305 request_info.url = GURL("https://www.example.com/");
14306 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914307 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014308 request_info.traffic_annotation =
14309 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714310
[email protected]bd0b6772011-01-11 19:59:3014311 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114312 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014313
14314 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14315 // return successfully after reading up to the peer's Certificate message.
14316 // This is to allow the caller to call SSLClientSocket::Write(), which can
14317 // enqueue application data to be sent in the same packet as the
14318 // ChangeCipherSpec and Finished messages.
14319 // The actual handshake will be finished when SSLClientSocket::Read() is
14320 // called, which expects to process the peer's ChangeCipherSpec and
14321 // Finished messages. If there was an error negotiating with the peer,
14322 // such as due to the peer requiring a client certificate when none was
14323 // supplied, the alert sent by the peer won't be processed until Read() is
14324 // called.
14325
14326 // Like the non-False Start case, when a client certificate is requested by
14327 // the peer, the handshake is aborted during the Connect() call.
14328 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914329 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014330 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914332 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714333 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014334
14335 // When a client certificate is supplied, Connect() will not be aborted
14336 // when the peer requests the certificate. Instead, the handshake will
14337 // artificially succeed, allowing the caller to write the HTTP request to
14338 // the socket. The handshake messages are not processed until Read() is
14339 // called, which then detects that the handshake was aborted, due to the
14340 // peer sending a handshake_failure because it requires a client
14341 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914342 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014343 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714344 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914345 MockRead data2_reads[] = {
14346 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014347 };
ttuttle859dc7a2015-04-23 19:42:2914348 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714349 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014350
14351 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714352 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14353 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914354 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014355 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914357 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714358 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014359
[email protected]80c75f682012-05-26 16:22:1714360 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14361 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914362 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714363 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914365 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714366 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714367
[email protected]7799de12013-05-30 05:52:5114368 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914369 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114370 ssl_data5.cert_request_info = cert_request.get();
14371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914372 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114373 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14374
danakj1fd259a02016-04-16 03:17:0914375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014377
[email protected]bd0b6772011-01-11 19:59:3014378 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114379 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014380 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114381 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014382
14383 // Complete the SSL handshake, which should abort due to requiring a
14384 // client certificate.
14385 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114386 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014387
14388 // Indicate that no certificate should be supplied. From the perspective
14389 // of SSLClientCertCache, NULL is just as meaningful as a real
14390 // certificate, so this is the same as supply a
14391 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614392 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114393 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014394
14395 // Ensure the certificate was added to the client auth cache before
14396 // allowing the connection to continue restarting.
14397 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414398 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114399 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414400 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214401 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014402
[email protected]bd0b6772011-01-11 19:59:3014403 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714404 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14405 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014406 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114407 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014408
14409 // Ensure that the client certificate is removed from the cache on a
14410 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114411 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414412 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014413}
14414
[email protected]8c405132011-01-11 22:03:1814415// Ensure that a client certificate is removed from the SSL client auth
14416// cache when:
14417// 1) An HTTPS proxy is involved.
14418// 3) The HTTPS proxy requests a client certificate.
14419// 4) The client supplies an invalid/unacceptable certificate for the
14420// proxy.
14421// The test is repeated twice, first for connecting to an HTTPS endpoint,
14422// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114423TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Lily Houghton8c2f97d2018-01-22 05:06:5914424 session_deps_.proxy_resolution_service =
14425 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114426 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714427 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814428
14429 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114430 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814431
14432 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14433 // [ssl_]data[1-3]. Rather than represending the endpoint
14434 // (www.example.com:443), they represent failures with the HTTPS proxy
14435 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914436 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814437 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914439 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714440 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814441
ttuttle859dc7a2015-04-23 19:42:2914442 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814443 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714444 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914445 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714446 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814447
[email protected]80c75f682012-05-26 16:22:1714448 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14449#if 0
ttuttle859dc7a2015-04-23 19:42:2914450 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814451 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914453 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714454 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714455#endif
[email protected]8c405132011-01-11 22:03:1814456
ttuttle859dc7a2015-04-23 19:42:2914457 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814458 requests[0].url = GURL("https://www.example.com/");
14459 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914460 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014461 requests[0].traffic_annotation =
14462 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814463
14464 requests[1].url = GURL("http://www.example.com/");
14465 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914466 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014467 requests[1].traffic_annotation =
14468 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814469
14470 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714471 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814474
14475 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114476 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014477 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114478 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814479
14480 // Complete the SSL handshake, which should abort due to requiring a
14481 // client certificate.
14482 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114483 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814484
14485 // Indicate that no certificate should be supplied. From the perspective
14486 // of SSLClientCertCache, NULL is just as meaningful as a real
14487 // certificate, so this is the same as supply a
14488 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614489 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114490 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814491
14492 // Ensure the certificate was added to the client auth cache before
14493 // allowing the connection to continue restarting.
14494 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414495 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114496 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414497 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214498 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814499 // Ensure the certificate was NOT cached for the endpoint. This only
14500 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114501 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414502 HostPortPair("www.example.com", 443), &client_cert,
14503 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814504
14505 // Restart the handshake. This will consume ssl_data2, which fails, and
14506 // then consume ssl_data3, which should also fail. The result code is
14507 // checked against what ssl_data3 should return.
14508 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114509 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814510
14511 // Now that the new handshake has failed, ensure that the client
14512 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114513 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414514 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114515 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414516 HostPortPair("www.example.com", 443), &client_cert,
14517 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814518 }
14519}
14520
bncd16676a2016-07-20 16:23:0114521TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614522 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914523 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914524 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614525
bnc032658ba2016-09-26 18:17:1514526 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614527
bncdf80d44fd2016-07-15 20:27:4114528 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914529 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814530 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114531 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714532 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614533 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114534 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614535 };
bnc42331402016-07-25 13:36:1514536 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114537 SpdySerializedFrame host1_resp_body(
14538 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514539 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114540 SpdySerializedFrame host2_resp_body(
14541 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614542 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114543 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14544 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314545 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614546 };
14547
eroman36d84e54432016-03-17 03:23:0214548 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214549 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314550 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14551 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714552 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614553
[email protected]aa22b242011-11-16 18:58:2914554 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614555 HttpRequestInfo request1;
14556 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314557 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614558 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014559 request1.traffic_annotation =
14560 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014561 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614562
tfarina42834112016-09-22 13:38:2014563 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14565 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614566
14567 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214568 ASSERT_TRUE(response);
14569 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214570 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614571
14572 std::string response_data;
robpercival214763f2016-07-01 23:27:0114573 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614574 EXPECT_EQ("hello!", response_data);
14575
bnca4d611d2016-09-22 19:55:3714576 // Preload mail.example.com into HostCache.
14577 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014578 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614579 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014580 std::unique_ptr<HostResolver::Request> request;
14581 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14582 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014583 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114586 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614587
14588 HttpRequestInfo request2;
14589 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714590 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614591 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014592 request2.traffic_annotation =
14593 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014594 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614595
tfarina42834112016-09-22 13:38:2014596 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14598 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614599
14600 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214601 ASSERT_TRUE(response);
14602 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214603 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614604 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214605 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114606 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614607 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614608}
14609
bncd16676a2016-07-20 16:23:0114610TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214611 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914612 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214614
bnc032658ba2016-09-26 18:17:1514615 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214616
bncdf80d44fd2016-07-15 20:27:4114617 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914618 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814619 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114620 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714621 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214622 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114623 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214624 };
bnc42331402016-07-25 13:36:1514625 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114626 SpdySerializedFrame host1_resp_body(
14627 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514628 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114629 SpdySerializedFrame host2_resp_body(
14630 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214631 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114632 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14633 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314634 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214635 };
14636
eroman36d84e54432016-03-17 03:23:0214637 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214638 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314639 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14640 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714641 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214642
14643 TestCompletionCallback callback;
14644 HttpRequestInfo request1;
14645 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314646 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214647 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014648 request1.traffic_annotation =
14649 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014650 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214651
tfarina42834112016-09-22 13:38:2014652 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14654 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214655
14656 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214657 ASSERT_TRUE(response);
14658 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214659 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214660
14661 std::string response_data;
robpercival214763f2016-07-01 23:27:0114662 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214663 EXPECT_EQ("hello!", response_data);
14664
14665 HttpRequestInfo request2;
14666 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714667 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214668 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014669 request2.traffic_annotation =
14670 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014671 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214672
tfarina42834112016-09-22 13:38:2014673 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14675 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214676
14677 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214678 ASSERT_TRUE(response);
14679 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214680 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214681 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214682 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114683 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214684 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214685}
14686
bnc8016c1f2017-03-31 02:11:2914687// Regression test for https://crbug.com/546991.
14688// The server might not be able to serve an IP pooled request, and might send a
14689// 421 Misdirected Request response status to indicate this.
14690// HttpNetworkTransaction should reset the request and retry without IP pooling.
14691TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14692 // Two hosts resolve to the same IP address.
14693 const std::string ip_addr = "1.2.3.4";
14694 IPAddress ip;
14695 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14696 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14697
Jeremy Roman0579ed62017-08-29 15:56:1914698 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914699 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14700 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14701
14702 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14703
14704 // Two requests on the first connection.
14705 SpdySerializedFrame req1(
14706 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14707 spdy_util_.UpdateWithStreamDestruction(1);
14708 SpdySerializedFrame req2(
14709 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14710 SpdySerializedFrame rst(
14711 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14712 MockWrite writes1[] = {
14713 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14714 CreateMockWrite(rst, 6),
14715 };
14716
14717 // The first one succeeds, the second gets error 421 Misdirected Request.
14718 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14719 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14720 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714721 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914722 SpdySerializedFrame resp2(
14723 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14724 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14725 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14726
14727 MockConnect connect1(ASYNC, OK, peer_addr);
14728 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14729 arraysize(writes1));
14730 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14731
14732 AddSSLSocketData();
14733
14734 // Retry the second request on a second connection.
14735 SpdyTestUtil spdy_util2;
14736 SpdySerializedFrame req3(
14737 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14738 MockWrite writes2[] = {
14739 CreateMockWrite(req3, 0),
14740 };
14741
14742 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14743 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14744 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14745 MockRead(ASYNC, 0, 3)};
14746
14747 MockConnect connect2(ASYNC, OK, peer_addr);
14748 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14749 arraysize(writes2));
14750 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14751
14752 AddSSLSocketData();
14753
14754 // Preload mail.example.org into HostCache.
14755 HostPortPair host_port("mail.example.org", 443);
14756 HostResolver::RequestInfo resolve_info(host_port);
14757 AddressList ignored;
14758 std::unique_ptr<HostResolver::Request> request;
14759 TestCompletionCallback callback;
14760 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14761 &ignored, callback.callback(),
14762 &request, NetLogWithSource());
14763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14764 rv = callback.WaitForResult();
14765 EXPECT_THAT(rv, IsOk());
14766
14767 HttpRequestInfo request1;
14768 request1.method = "GET";
14769 request1.url = GURL("https://www.example.org/");
14770 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014771 request1.traffic_annotation =
14772 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914773 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14774
14775 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14777 rv = callback.WaitForResult();
14778 EXPECT_THAT(rv, IsOk());
14779
14780 const HttpResponseInfo* response = trans1.GetResponseInfo();
14781 ASSERT_TRUE(response);
14782 ASSERT_TRUE(response->headers);
14783 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14784 EXPECT_TRUE(response->was_fetched_via_spdy);
14785 EXPECT_TRUE(response->was_alpn_negotiated);
14786 std::string response_data;
14787 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14788 EXPECT_EQ("hello!", response_data);
14789
14790 HttpRequestInfo request2;
14791 request2.method = "GET";
14792 request2.url = GURL("https://mail.example.org/");
14793 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014794 request2.traffic_annotation =
14795 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914796 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14797
14798 BoundTestNetLog log;
14799 rv = trans2.Start(&request2, callback.callback(), log.bound());
14800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14801 rv = callback.WaitForResult();
14802 EXPECT_THAT(rv, IsOk());
14803
14804 response = trans2.GetResponseInfo();
14805 ASSERT_TRUE(response);
14806 ASSERT_TRUE(response->headers);
14807 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14808 EXPECT_TRUE(response->was_fetched_via_spdy);
14809 EXPECT_TRUE(response->was_alpn_negotiated);
14810 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14811 EXPECT_EQ("hello!", response_data);
14812
14813 TestNetLogEntry::List entries;
14814 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914815 ExpectLogContainsSomewhere(
14816 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914817 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914818}
14819
14820// Test that HTTP 421 responses are properly returned to the caller if received
14821// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14822// portions of the response.
14823TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14824 // Two hosts resolve to the same IP address.
14825 const std::string ip_addr = "1.2.3.4";
14826 IPAddress ip;
14827 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14828 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14829
Jeremy Roman0579ed62017-08-29 15:56:1914830 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914831 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14832 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14833
14834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14835
14836 // Two requests on the first connection.
14837 SpdySerializedFrame req1(
14838 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14839 spdy_util_.UpdateWithStreamDestruction(1);
14840 SpdySerializedFrame req2(
14841 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14842 SpdySerializedFrame rst(
14843 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14844 MockWrite writes1[] = {
14845 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14846 CreateMockWrite(rst, 6),
14847 };
14848
14849 // The first one succeeds, the second gets error 421 Misdirected Request.
14850 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14851 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14852 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714853 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914854 SpdySerializedFrame resp2(
14855 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14856 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14857 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14858
14859 MockConnect connect1(ASYNC, OK, peer_addr);
14860 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14861 arraysize(writes1));
14862 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14863
14864 AddSSLSocketData();
14865
14866 // Retry the second request on a second connection. It returns 421 Misdirected
14867 // Retry again.
14868 SpdyTestUtil spdy_util2;
14869 SpdySerializedFrame req3(
14870 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14871 MockWrite writes2[] = {
14872 CreateMockWrite(req3, 0),
14873 };
14874
14875 SpdySerializedFrame resp3(
14876 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14877 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14878 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14879 MockRead(ASYNC, 0, 3)};
14880
14881 MockConnect connect2(ASYNC, OK, peer_addr);
14882 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14883 arraysize(writes2));
14884 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14885
14886 AddSSLSocketData();
14887
14888 // Preload mail.example.org into HostCache.
14889 HostPortPair host_port("mail.example.org", 443);
14890 HostResolver::RequestInfo resolve_info(host_port);
14891 AddressList ignored;
14892 std::unique_ptr<HostResolver::Request> request;
14893 TestCompletionCallback callback;
14894 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14895 &ignored, callback.callback(),
14896 &request, NetLogWithSource());
14897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14898 rv = callback.WaitForResult();
14899 EXPECT_THAT(rv, IsOk());
14900
14901 HttpRequestInfo request1;
14902 request1.method = "GET";
14903 request1.url = GURL("https://www.example.org/");
14904 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014905 request1.traffic_annotation =
14906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914907 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14908
14909 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14911 rv = callback.WaitForResult();
14912 EXPECT_THAT(rv, IsOk());
14913
14914 const HttpResponseInfo* response = trans1.GetResponseInfo();
14915 ASSERT_TRUE(response);
14916 ASSERT_TRUE(response->headers);
14917 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14918 EXPECT_TRUE(response->was_fetched_via_spdy);
14919 EXPECT_TRUE(response->was_alpn_negotiated);
14920 std::string response_data;
14921 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14922 EXPECT_EQ("hello!", response_data);
14923
14924 HttpRequestInfo request2;
14925 request2.method = "GET";
14926 request2.url = GURL("https://mail.example.org/");
14927 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014928 request2.traffic_annotation =
14929 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914930 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14931
14932 BoundTestNetLog log;
14933 rv = trans2.Start(&request2, callback.callback(), log.bound());
14934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14935 rv = callback.WaitForResult();
14936 EXPECT_THAT(rv, IsOk());
14937
14938 // After a retry, the 421 Misdirected Request is reported back up to the
14939 // caller.
14940 response = trans2.GetResponseInfo();
14941 ASSERT_TRUE(response);
14942 ASSERT_TRUE(response->headers);
14943 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14944 EXPECT_TRUE(response->was_fetched_via_spdy);
14945 EXPECT_TRUE(response->was_alpn_negotiated);
14946 EXPECT_TRUE(response->ssl_info.cert);
14947 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14948 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914949}
14950
bnc6dcd8192017-05-25 20:11:5014951class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614952 public:
14953 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014954 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714955 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614956
dchengb03027d2014-10-21 12:00:2014957 int ResolveFromCache(const RequestInfo& info,
14958 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014959 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014960 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014961 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014962 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614963 return rv;
14964 }
14965
[email protected]e3ceb682011-06-28 23:55:4614966 private:
[email protected]e3ceb682011-06-28 23:55:4614967 const HostPortPair host_port_;
14968};
14969
bncd16676a2016-07-20 16:23:0114970TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314971 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614972 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914973 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714974 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914975 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614976
bnc032658ba2016-09-26 18:17:1514977 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614978
bncdf80d44fd2016-07-15 20:27:4114979 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914980 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814981 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114982 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714983 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614984 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114985 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614986 };
bnc42331402016-07-25 13:36:1514987 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114988 SpdySerializedFrame host1_resp_body(
14989 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514990 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114991 SpdySerializedFrame host2_resp_body(
14992 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614993 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114994 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14995 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314996 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614997 };
14998
eroman36d84e54432016-03-17 03:23:0214999 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215000 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1315001 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
15002 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0715003 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615004
[email protected]aa22b242011-11-16 18:58:2915005 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615006 HttpRequestInfo request1;
15007 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315008 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615009 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015010 request1.traffic_annotation =
15011 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015012 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615013
tfarina42834112016-09-22 13:38:2015014 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15016 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615017
15018 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215019 ASSERT_TRUE(response);
15020 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215021 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615022
15023 std::string response_data;
robpercival214763f2016-07-01 23:27:0115024 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615025 EXPECT_EQ("hello!", response_data);
15026
15027 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715028 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615029 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015030 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015031 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15032 &ignored, callback.callback(),
15033 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715035 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115036 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615037
15038 HttpRequestInfo request2;
15039 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715040 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615041 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015042 request2.traffic_annotation =
15043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015044 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615045
tfarina42834112016-09-22 13:38:2015046 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15048 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615049
15050 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215051 ASSERT_TRUE(response);
15052 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215053 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615054 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215055 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115056 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615057 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615058}
15059
bncd16676a2016-07-20 16:23:0115060TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315061 const std::string https_url = "https://www.example.org:8080/";
15062 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415063
15064 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4115065 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915066 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415067
15068 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115069 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415070 };
15071
bnc42331402016-07-25 13:36:1515072 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115073 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15074 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915075 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415076
rch8e6c6c42015-05-01 14:05:1315077 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15078 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415079 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715080 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415081
15082 // HTTP GET for the HTTP URL
15083 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315084 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415085 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315086 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415087 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415088 };
15089
15090 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315091 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15092 MockRead(ASYNC, 2, "hello"),
15093 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415094 };
15095
rch8e6c6c42015-05-01 14:05:1315096 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15097 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0415098
[email protected]8450d722012-07-02 19:14:0415099 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615100 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15102 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15103 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415104
danakj1fd259a02016-04-16 03:17:0915105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415106
15107 // Start the first transaction to set up the SpdySession
15108 HttpRequestInfo request1;
15109 request1.method = "GET";
15110 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415111 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015112 request1.traffic_annotation =
15113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015114 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415115 TestCompletionCallback callback1;
15116 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015117 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515118 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415119
robpercival214763f2016-07-01 23:27:0115120 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415121 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15122
15123 // Now, start the HTTP request
15124 HttpRequestInfo request2;
15125 request2.method = "GET";
15126 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415127 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015128 request2.traffic_annotation =
15129 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015130 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415131 TestCompletionCallback callback2;
15132 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015133 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515134 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415135
robpercival214763f2016-07-01 23:27:0115136 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415137 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15138}
15139
bnc5452e2a2015-05-08 16:27:4215140// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15141// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115142TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515143 url::SchemeHostPort server("https", "www.example.org", 443);
15144 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215145
bnc8bef8da22016-05-30 01:28:2515146 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215147 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615148 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215149 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15150
15151 // No data should be read from the alternative, because HTTP/1.1 is
15152 // negotiated.
15153 StaticSocketDataProvider data;
15154 session_deps_.socket_factory->AddSocketDataProvider(&data);
15155
15156 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615157 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215158 // mocked. This way the request relies on the alternate Job.
15159 StaticSocketDataProvider data_refused;
15160 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15161 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15162
zhongyi3d4a55e72016-04-22 20:36:4615163 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915164 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015165 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215166 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115167 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215168 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115169 http_server_properties->SetHttp2AlternativeService(
15170 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215171
bnc5452e2a2015-05-08 16:27:4215172 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215174 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515175 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015176 request.traffic_annotation =
15177 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215178 TestCompletionCallback callback;
15179
15180 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215181 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015182 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215183 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215184}
15185
bnc40448a532015-05-11 19:13:1415186// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615187// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415188// succeeds, the request should succeed, even if the latter fails because
15189// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115190TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515191 url::SchemeHostPort server("https", "www.example.org", 443);
15192 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415193
15194 // Negotiate HTTP/1.1 with alternative.
15195 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615196 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415197 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15198
15199 // No data should be read from the alternative, because HTTP/1.1 is
15200 // negotiated.
15201 StaticSocketDataProvider data;
15202 session_deps_.socket_factory->AddSocketDataProvider(&data);
15203
zhongyi3d4a55e72016-04-22 20:36:4615204 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415205 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615206 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415207 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15208
15209 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515210 MockWrite("GET / HTTP/1.1\r\n"
15211 "Host: www.example.org\r\n"
15212 "Connection: keep-alive\r\n\r\n"),
15213 MockWrite("GET /second HTTP/1.1\r\n"
15214 "Host: www.example.org\r\n"
15215 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415216 };
15217
15218 MockRead http_reads[] = {
15219 MockRead("HTTP/1.1 200 OK\r\n"),
15220 MockRead("Content-Type: text/html\r\n"),
15221 MockRead("Content-Length: 6\r\n\r\n"),
15222 MockRead("foobar"),
15223 MockRead("HTTP/1.1 200 OK\r\n"),
15224 MockRead("Content-Type: text/html\r\n"),
15225 MockRead("Content-Length: 7\r\n\r\n"),
15226 MockRead("another"),
15227 };
15228 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15229 http_writes, arraysize(http_writes));
15230 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15231
zhongyi3d4a55e72016-04-22 20:36:4615232 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015234 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415235 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115236 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215237 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115238 http_server_properties->SetHttp2AlternativeService(
15239 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415240
15241 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15242 HttpRequestInfo request1;
15243 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515244 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415245 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015246 request1.traffic_annotation =
15247 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415248 TestCompletionCallback callback1;
15249
tfarina42834112016-09-22 13:38:2015250 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415251 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115252 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415253
15254 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215255 ASSERT_TRUE(response1);
15256 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415257 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15258
15259 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115260 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415261 EXPECT_EQ("foobar", response_data1);
15262
15263 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15264 // for alternative service.
15265 EXPECT_TRUE(
15266 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15267
zhongyi3d4a55e72016-04-22 20:36:4615268 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415269 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615270 // to server.
bnc40448a532015-05-11 19:13:1415271 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15272 HttpRequestInfo request2;
15273 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515274 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415275 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015276 request2.traffic_annotation =
15277 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415278 TestCompletionCallback callback2;
15279
tfarina42834112016-09-22 13:38:2015280 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415281 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115282 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415283
15284 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215285 ASSERT_TRUE(response2);
15286 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415287 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15288
15289 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115290 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415291 EXPECT_EQ("another", response_data2);
15292}
15293
bnc5452e2a2015-05-08 16:27:4215294// Alternative service requires HTTP/2 (or SPDY), but there is already a
15295// HTTP/1.1 socket open to the alternative server. That socket should not be
15296// used.
bncd16676a2016-07-20 16:23:0115297TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615298 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215299 HostPortPair alternative("alternative.example.org", 443);
15300 std::string origin_url = "https://origin.example.org:443";
15301 std::string alternative_url = "https://alternative.example.org:443";
15302
15303 // Negotiate HTTP/1.1 with alternative.example.org.
15304 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615305 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15307
15308 // HTTP/1.1 data for |request1| and |request2|.
15309 MockWrite http_writes[] = {
15310 MockWrite(
15311 "GET / HTTP/1.1\r\n"
15312 "Host: alternative.example.org\r\n"
15313 "Connection: keep-alive\r\n\r\n"),
15314 MockWrite(
15315 "GET / HTTP/1.1\r\n"
15316 "Host: alternative.example.org\r\n"
15317 "Connection: keep-alive\r\n\r\n"),
15318 };
15319
15320 MockRead http_reads[] = {
15321 MockRead(
15322 "HTTP/1.1 200 OK\r\n"
15323 "Content-Type: text/html; charset=iso-8859-1\r\n"
15324 "Content-Length: 40\r\n\r\n"
15325 "first HTTP/1.1 response from alternative"),
15326 MockRead(
15327 "HTTP/1.1 200 OK\r\n"
15328 "Content-Type: text/html; charset=iso-8859-1\r\n"
15329 "Content-Length: 41\r\n\r\n"
15330 "second HTTP/1.1 response from alternative"),
15331 };
15332 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15333 http_writes, arraysize(http_writes));
15334 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15335
15336 // This test documents that an alternate Job should not pool to an already
15337 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615338 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215339 StaticSocketDataProvider data_refused;
15340 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15341 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15342
zhongyi3d4a55e72016-04-22 20:36:4615343 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015345 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215346 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115347 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215348 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115349 http_server_properties->SetHttp2AlternativeService(
15350 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215351
15352 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215353 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615354 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215355 request1.method = "GET";
15356 request1.url = GURL(alternative_url);
15357 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015358 request1.traffic_annotation =
15359 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215360 TestCompletionCallback callback1;
15361
tfarina42834112016-09-22 13:38:2015362 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115363 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615364 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215365 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215366 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215367 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215368 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215369 EXPECT_FALSE(response1->was_fetched_via_spdy);
15370 std::string response_data1;
bnc691fda62016-08-12 00:43:1615371 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215372 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15373
15374 // Request for origin.example.org, which has an alternative service. This
15375 // will start two Jobs: the alternative looks for connections to pool to,
15376 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615377 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215378 // this request fails.
bnc5452e2a2015-05-08 16:27:4215379 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615380 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215381 request2.method = "GET";
15382 request2.url = GURL(origin_url);
15383 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015384 request2.traffic_annotation =
15385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215386 TestCompletionCallback callback2;
15387
tfarina42834112016-09-22 13:38:2015388 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115389 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215390
15391 // Another transaction to alternative. This is to test that the HTTP/1.1
15392 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215393 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615394 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215395 request3.method = "GET";
15396 request3.url = GURL(alternative_url);
15397 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015398 request3.traffic_annotation =
15399 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215400 TestCompletionCallback callback3;
15401
tfarina42834112016-09-22 13:38:2015402 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115403 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615404 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215405 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215406 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215407 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215408 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215409 EXPECT_FALSE(response3->was_fetched_via_spdy);
15410 std::string response_data3;
bnc691fda62016-08-12 00:43:1615411 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215412 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15413}
15414
bncd16676a2016-07-20 16:23:0115415TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315416 const std::string https_url = "https://www.example.org:8080/";
15417 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415418
rdsmithebb50aa2015-11-12 03:44:3815419 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115420 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815421
[email protected]8450d722012-07-02 19:14:0415422 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315423 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115424 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415425 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115426 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915427 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115428 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215429 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915430
15431 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915432 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715433 req2_block[kHttp2MethodHeader] = "GET";
15434 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15435 req2_block[kHttp2SchemeHeader] = "http";
15436 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115437 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515438 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415439
15440 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115441 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15442 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415443 };
15444
bncdf80d44fd2016-07-15 20:27:4115445 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515446 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115447 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515448 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115449 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15450 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815451 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115452 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815453 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515454 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115455 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315456 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115457 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315458 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115459 CreateMockRead(wrapped_resp1, 4),
15460 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315461 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115462 CreateMockRead(resp2, 8),
15463 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315464 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15465 };
[email protected]8450d722012-07-02 19:14:0415466
mmenke666a6fea2015-12-19 04:16:3315467 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15468 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415469 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715470 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415471
Lily Houghton8c2f97d2018-01-22 05:06:5915472 session_deps_.proxy_resolution_service =
15473 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115474 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715475 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415476 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615477 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415479 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615480 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15482 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415483
danakj1fd259a02016-04-16 03:17:0915484 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415485
15486 // Start the first transaction to set up the SpdySession
15487 HttpRequestInfo request1;
15488 request1.method = "GET";
15489 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415490 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015491 request1.traffic_annotation =
15492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015493 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415494 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015495 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415496
mmenke666a6fea2015-12-19 04:16:3315497 // This pause is a hack to avoid running into https://crbug.com/497228.
15498 data1.RunUntilPaused();
15499 base::RunLoop().RunUntilIdle();
15500 data1.Resume();
robpercival214763f2016-07-01 23:27:0115501 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415502 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15503
[email protected]f6c63db52013-02-02 00:35:2215504 LoadTimingInfo load_timing_info1;
15505 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15506 TestLoadTimingNotReusedWithPac(load_timing_info1,
15507 CONNECT_TIMING_HAS_SSL_TIMES);
15508
mmenke666a6fea2015-12-19 04:16:3315509 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415510 HttpRequestInfo request2;
15511 request2.method = "GET";
15512 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415513 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015514 request2.traffic_annotation =
15515 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015516 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415517 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015518 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415519
mmenke666a6fea2015-12-19 04:16:3315520 // This pause is a hack to avoid running into https://crbug.com/497228.
15521 data1.RunUntilPaused();
15522 base::RunLoop().RunUntilIdle();
15523 data1.Resume();
robpercival214763f2016-07-01 23:27:0115524 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315525
[email protected]8450d722012-07-02 19:14:0415526 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215527
15528 LoadTimingInfo load_timing_info2;
15529 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15530 // The established SPDY sessions is considered reused by the HTTP request.
15531 TestLoadTimingReusedWithPac(load_timing_info2);
15532 // HTTP requests over a SPDY session should have a different connection
15533 // socket_log_id than requests over a tunnel.
15534 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415535}
15536
[email protected]2d88e7d2012-07-19 17:55:1715537// Test that in the case where we have a SPDY session to a SPDY proxy
15538// that we do not pool other origins that resolve to the same IP when
15539// the certificate does not match the new origin.
15540// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115541TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315542 const std::string url1 = "http://www.example.org/";
15543 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715544 const std::string ip_addr = "1.2.3.4";
15545
rdsmithebb50aa2015-11-12 03:44:3815546 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115547 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815548
[email protected]2d88e7d2012-07-19 17:55:1715549 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615550 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315551 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115552 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515553 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715554
15555 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115556 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715557 };
15558
bnc42331402016-07-25 13:36:1515559 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115560 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715561 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115562 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15563 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715564 };
15565
mmenke666a6fea2015-12-19 04:16:3315566 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15567 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215568 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915569 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715570 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15571 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315572 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715573
15574 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115575 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915576 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715577
15578 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115579 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715580 };
15581
bnc42331402016-07-25 13:36:1515582 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115583 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15584 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315585 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715586
mmenke666a6fea2015-12-19 04:16:3315587 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15588 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715589 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315590 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715591
15592 // Set up a proxy config that sends HTTP requests to a proxy, and
15593 // all others direct.
15594 ProxyConfig proxy_config;
15595 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Lily Houghton8c2f97d2018-01-22 05:06:5915596 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1915597 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815598 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715599
bncce36dca22015-04-21 22:11:2315600 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615601 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715602 // Load a valid cert. Note, that this does not need to
15603 // be valid for proxy because the MockSSLClientSocket does
15604 // not actually verify it. But SpdySession will use this
15605 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915606 ssl1.ssl_info.cert =
15607 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15608 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15610 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715611
15612 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615613 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15615 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715616
Jeremy Roman0579ed62017-08-29 15:56:1915617 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315618 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715619 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715620
danakj1fd259a02016-04-16 03:17:0915621 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715622
15623 // Start the first transaction to set up the SpdySession
15624 HttpRequestInfo request1;
15625 request1.method = "GET";
15626 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715627 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015628 request1.traffic_annotation =
15629 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015630 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715631 TestCompletionCallback callback1;
15632 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015633 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315634 // This pause is a hack to avoid running into https://crbug.com/497228.
15635 data1.RunUntilPaused();
15636 base::RunLoop().RunUntilIdle();
15637 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715638
robpercival214763f2016-07-01 23:27:0115639 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715640 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15641
15642 // Now, start the HTTP request
15643 HttpRequestInfo request2;
15644 request2.method = "GET";
15645 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715646 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015647 request2.traffic_annotation =
15648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015649 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715650 TestCompletionCallback callback2;
15651 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015652 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515653 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715654
15655 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115656 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715657 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15658}
15659
[email protected]85f97342013-04-17 06:12:2415660// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15661// error) in SPDY session, removes the socket from pool and closes the SPDY
15662// session. Verify that new url's from the same HttpNetworkSession (and a new
15663// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115664TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315665 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415666
15667 MockRead reads1[] = {
15668 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15669 };
15670
mmenke11eb5152015-06-09 14:50:5015671 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415672
bncdf80d44fd2016-07-15 20:27:4115673 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915674 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415675 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115676 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415677 };
15678
bnc42331402016-07-25 13:36:1515679 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115680 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415681 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115682 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15683 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415684 };
15685
mmenke11eb5152015-06-09 14:50:5015686 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15687 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415688
[email protected]85f97342013-04-17 06:12:2415689 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615690 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15692 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415693
15694 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615695 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015696 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15697 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415698
danakj1fd259a02016-04-16 03:17:0915699 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015700 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415701
15702 // Start the first transaction to set up the SpdySession and verify that
15703 // connection was closed.
15704 HttpRequestInfo request1;
15705 request1.method = "GET";
15706 request1.url = GURL(https_url);
15707 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015708 request1.traffic_annotation =
15709 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015710 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415711 TestCompletionCallback callback1;
15712 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015713 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115714 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415715
15716 // Now, start the second request and make sure it succeeds.
15717 HttpRequestInfo request2;
15718 request2.method = "GET";
15719 request2.url = GURL(https_url);
15720 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015721 request2.traffic_annotation =
15722 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015723 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415724 TestCompletionCallback callback2;
15725 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015726 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415727
robpercival214763f2016-07-01 23:27:0115728 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415729 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15730}
15731
bncd16676a2016-07-20 16:23:0115732TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315733 ClientSocketPoolManager::set_max_sockets_per_group(
15734 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15735 ClientSocketPoolManager::set_max_sockets_per_pool(
15736 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15737
15738 // Use two different hosts with different IPs so they don't get pooled.
15739 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15740 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315742
15743 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615744 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315745 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615746 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315747 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15748 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15749
bncdf80d44fd2016-07-15 20:27:4115750 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915751 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315752 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115753 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315754 };
bnc42331402016-07-25 13:36:1515755 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115756 SpdySerializedFrame host1_resp_body(
15757 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315758 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115759 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915760 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315761 };
15762
rdsmithebb50aa2015-11-12 03:44:3815763 // Use a separate test instance for the separate SpdySession that will be
15764 // created.
bncd16676a2016-07-20 16:23:0115765 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915766 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815767 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15768 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315769 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15770
bncdf80d44fd2016-07-15 20:27:4115771 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915772 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315773 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115774 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315775 };
bnc42331402016-07-25 13:36:1515776 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115777 SpdySerializedFrame host2_resp_body(
15778 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315779 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115780 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915781 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315782 };
15783
Jeremy Roman0579ed62017-08-29 15:56:1915784 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815785 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15786 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315787 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15788
15789 MockWrite http_write[] = {
15790 MockWrite("GET / HTTP/1.1\r\n"
15791 "Host: www.a.com\r\n"
15792 "Connection: keep-alive\r\n\r\n"),
15793 };
15794
15795 MockRead http_read[] = {
15796 MockRead("HTTP/1.1 200 OK\r\n"),
15797 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15798 MockRead("Content-Length: 6\r\n\r\n"),
15799 MockRead("hello!"),
15800 };
15801 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15802 http_write, arraysize(http_write));
15803 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15804
15805 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415806 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15807 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315808 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615809 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315810
15811 TestCompletionCallback callback;
15812 HttpRequestInfo request1;
15813 request1.method = "GET";
15814 request1.url = GURL("https://www.a.com/");
15815 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015816 request1.traffic_annotation =
15817 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815818 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915819 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315820
tfarina42834112016-09-22 13:38:2015821 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15823 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315824
15825 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215826 ASSERT_TRUE(response);
15827 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215828 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315829 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215830 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315831
15832 std::string response_data;
robpercival214763f2016-07-01 23:27:0115833 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315834 EXPECT_EQ("hello!", response_data);
15835 trans.reset();
15836 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615837 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315838
15839 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415840 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15841 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315842 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615843 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315844 HttpRequestInfo request2;
15845 request2.method = "GET";
15846 request2.url = GURL("https://www.b.com/");
15847 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015848 request2.traffic_annotation =
15849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815850 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915851 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315852
tfarina42834112016-09-22 13:38:2015853 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115854 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15855 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315856
15857 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215858 ASSERT_TRUE(response);
15859 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215860 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315861 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215862 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115863 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315864 EXPECT_EQ("hello!", response_data);
15865 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615866 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315867 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615868 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315869
15870 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415871 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15872 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315873 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615874 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315875 HttpRequestInfo request3;
15876 request3.method = "GET";
15877 request3.url = GURL("http://www.a.com/");
15878 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015879 request3.traffic_annotation =
15880 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815881 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915882 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315883
tfarina42834112016-09-22 13:38:2015884 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15886 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315887
15888 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215889 ASSERT_TRUE(response);
15890 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315891 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15892 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215893 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115894 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315895 EXPECT_EQ("hello!", response_data);
15896 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615897 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315898 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615899 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315900}
15901
bncd16676a2016-07-20 16:23:0115902TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415903 HttpRequestInfo request;
15904 request.method = "GET";
bncce36dca22015-04-21 22:11:2315905 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015906 request.traffic_annotation =
15907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415908
danakj1fd259a02016-04-16 03:17:0915909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615910 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415911
ttuttled9dbc652015-09-29 20:00:5915912 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415913 StaticSocketDataProvider data;
15914 data.set_connect_data(mock_connect);
15915 session_deps_.socket_factory->AddSocketDataProvider(&data);
15916
15917 TestCompletionCallback callback;
15918
tfarina42834112016-09-22 13:38:2015919 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415921
15922 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115923 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415924
[email protected]79e1fd62013-06-20 06:50:0415925 // We don't care whether this succeeds or fails, but it shouldn't crash.
15926 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615927 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715928
15929 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615930 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715931 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115932 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915933
15934 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615935 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915936 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415937}
15938
bncd16676a2016-07-20 16:23:0115939TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415940 HttpRequestInfo request;
15941 request.method = "GET";
bncce36dca22015-04-21 22:11:2315942 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015943 request.traffic_annotation =
15944 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415945
danakj1fd259a02016-04-16 03:17:0915946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615947 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415948
ttuttled9dbc652015-09-29 20:00:5915949 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415950 StaticSocketDataProvider data;
15951 data.set_connect_data(mock_connect);
15952 session_deps_.socket_factory->AddSocketDataProvider(&data);
15953
15954 TestCompletionCallback callback;
15955
tfarina42834112016-09-22 13:38:2015956 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415958
15959 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115960 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415961
[email protected]79e1fd62013-06-20 06:50:0415962 // We don't care whether this succeeds or fails, but it shouldn't crash.
15963 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615964 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715965
15966 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615967 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715968 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115969 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915970
15971 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615972 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915973 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415974}
15975
bncd16676a2016-07-20 16:23:0115976TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415977 HttpRequestInfo request;
15978 request.method = "GET";
bncce36dca22015-04-21 22:11:2315979 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015980 request.traffic_annotation =
15981 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415982
danakj1fd259a02016-04-16 03:17:0915983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415985
15986 MockWrite data_writes[] = {
15987 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15988 };
15989 MockRead data_reads[] = {
15990 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15991 };
15992
15993 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15994 data_writes, arraysize(data_writes));
15995 session_deps_.socket_factory->AddSocketDataProvider(&data);
15996
15997 TestCompletionCallback callback;
15998
tfarina42834112016-09-22 13:38:2015999 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416001
16002 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116003 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416004
[email protected]79e1fd62013-06-20 06:50:0416005 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616006 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416007 EXPECT_TRUE(request_headers.HasHeader("Host"));
16008}
16009
bncd16676a2016-07-20 16:23:0116010TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416011 HttpRequestInfo request;
16012 request.method = "GET";
bncce36dca22015-04-21 22:11:2316013 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016014 request.traffic_annotation =
16015 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416016
danakj1fd259a02016-04-16 03:17:0916017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416019
16020 MockWrite data_writes[] = {
16021 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16022 };
16023 MockRead data_reads[] = {
16024 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16025 };
16026
16027 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16028 data_writes, arraysize(data_writes));
16029 session_deps_.socket_factory->AddSocketDataProvider(&data);
16030
16031 TestCompletionCallback callback;
16032
tfarina42834112016-09-22 13:38:2016033 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416035
16036 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116037 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416038
[email protected]79e1fd62013-06-20 06:50:0416039 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616040 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416041 EXPECT_TRUE(request_headers.HasHeader("Host"));
16042}
16043
bncd16676a2016-07-20 16:23:0116044TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416045 HttpRequestInfo request;
16046 request.method = "GET";
bncce36dca22015-04-21 22:11:2316047 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016048 request.traffic_annotation =
16049 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416050
danakj1fd259a02016-04-16 03:17:0916051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416053
16054 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316055 MockWrite(
16056 "GET / HTTP/1.1\r\n"
16057 "Host: www.example.org\r\n"
16058 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416059 };
16060 MockRead data_reads[] = {
16061 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16062 };
16063
16064 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16065 data_writes, arraysize(data_writes));
16066 session_deps_.socket_factory->AddSocketDataProvider(&data);
16067
16068 TestCompletionCallback callback;
16069
tfarina42834112016-09-22 13:38:2016070 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416072
16073 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116074 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416075
[email protected]79e1fd62013-06-20 06:50:0416076 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616077 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416078 EXPECT_TRUE(request_headers.HasHeader("Host"));
16079}
16080
bncd16676a2016-07-20 16:23:0116081TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416082 HttpRequestInfo request;
16083 request.method = "GET";
bncce36dca22015-04-21 22:11:2316084 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016085 request.traffic_annotation =
16086 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416087
danakj1fd259a02016-04-16 03:17:0916088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416090
16091 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316092 MockWrite(
16093 "GET / HTTP/1.1\r\n"
16094 "Host: www.example.org\r\n"
16095 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416096 };
16097 MockRead data_reads[] = {
16098 MockRead(ASYNC, ERR_CONNECTION_RESET),
16099 };
16100
16101 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16102 data_writes, arraysize(data_writes));
16103 session_deps_.socket_factory->AddSocketDataProvider(&data);
16104
16105 TestCompletionCallback callback;
16106
tfarina42834112016-09-22 13:38:2016107 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416109
16110 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116111 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416112
[email protected]79e1fd62013-06-20 06:50:0416113 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616114 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416115 EXPECT_TRUE(request_headers.HasHeader("Host"));
16116}
16117
bncd16676a2016-07-20 16:23:0116118TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416119 HttpRequestInfo request;
16120 request.method = "GET";
bncce36dca22015-04-21 22:11:2316121 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416122 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016123 request.traffic_annotation =
16124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416125
danakj1fd259a02016-04-16 03:17:0916126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416128
16129 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316130 MockWrite(
16131 "GET / HTTP/1.1\r\n"
16132 "Host: www.example.org\r\n"
16133 "Connection: keep-alive\r\n"
16134 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416135 };
16136 MockRead data_reads[] = {
16137 MockRead("HTTP/1.1 200 OK\r\n"
16138 "Content-Length: 5\r\n\r\n"
16139 "hello"),
16140 MockRead(ASYNC, ERR_UNEXPECTED),
16141 };
16142
16143 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
16144 data_writes, arraysize(data_writes));
16145 session_deps_.socket_factory->AddSocketDataProvider(&data);
16146
16147 TestCompletionCallback callback;
16148
tfarina42834112016-09-22 13:38:2016149 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416151
16152 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116153 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416154
16155 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616156 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416157 std::string foo;
16158 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16159 EXPECT_EQ("bar", foo);
16160}
16161
[email protected]bf828982013-08-14 18:01:4716162namespace {
16163
yhiranoa7e05bb2014-11-06 05:40:3916164// Fake HttpStream that simply records calls to SetPriority().
16165class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0316166 public base::SupportsWeakPtr<FakeStream> {
16167 public:
16168 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2716169 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0316170
16171 RequestPriority priority() const { return priority_; }
16172
dchengb03027d2014-10-21 12:00:2016173 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2716174 bool can_send_early,
dchengb03027d2014-10-21 12:00:2016175 RequestPriority priority,
tfarina42834112016-09-22 13:38:2016176 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2016177 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0316178 return ERR_IO_PENDING;
16179 }
16180
dchengb03027d2014-10-21 12:00:2016181 int SendRequest(const HttpRequestHeaders& request_headers,
16182 HttpResponseInfo* response,
16183 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0316184 ADD_FAILURE();
16185 return ERR_UNEXPECTED;
16186 }
16187
dchengb03027d2014-10-21 12:00:2016188 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0316189 ADD_FAILURE();
16190 return ERR_UNEXPECTED;
16191 }
16192
dchengb03027d2014-10-21 12:00:2016193 int ReadResponseBody(IOBuffer* buf,
16194 int buf_len,
16195 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0316196 ADD_FAILURE();
16197 return ERR_UNEXPECTED;
16198 }
16199
dchengb03027d2014-10-21 12:00:2016200 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0316201
dchengb03027d2014-10-21 12:00:2016202 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0316203 ADD_FAILURE();
16204 return false;
16205 }
16206
dchengb03027d2014-10-21 12:00:2016207 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0316208 ADD_FAILURE();
16209 return false;
16210 }
16211
dchengb03027d2014-10-21 12:00:2016212 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316213
mmenkebd84c392015-09-02 14:12:3416214 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0316215
sclittle4de1bab92015-09-22 21:28:2416216 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5916217 ADD_FAILURE();
16218 return 0;
16219 }
16220
sclittlebe1ccf62015-09-02 19:40:3616221 int64_t GetTotalSentBytes() const override {
16222 ADD_FAILURE();
16223 return 0;
16224 }
16225
dchengb03027d2014-10-21 12:00:2016226 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0316227 ADD_FAILURE();
16228 return false;
16229 }
16230
rchcd379012017-04-12 21:53:3216231 bool GetAlternativeService(
16232 AlternativeService* alternative_service) const override {
16233 ADD_FAILURE();
16234 return false;
16235 }
16236
dchengb03027d2014-10-21 12:00:2016237 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
16238
16239 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0316240 ADD_FAILURE();
16241 }
16242
ttuttled9dbc652015-09-29 20:00:5916243 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
16244
nharper78e6d2b2016-09-21 05:42:3516245 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
16246 TokenBindingType tb_type,
16247 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1416248 ADD_FAILURE();
16249 return ERR_NOT_IMPLEMENTED;
16250 }
16251
dchengb03027d2014-10-21 12:00:2016252 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0316253
zhongyica364fbb2015-12-12 03:39:1216254 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
16255
dchengb03027d2014-10-21 12:00:2016256 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0316257
yhiranoa7e05bb2014-11-06 05:40:3916258 HttpStream* RenewStreamForAuth() override { return NULL; }
16259
Andrey Kosyakov83a6eee2017-08-14 19:20:0416260 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
16261
[email protected]e86839fd2013-08-14 18:29:0316262 private:
16263 RequestPriority priority_;
16264
16265 DISALLOW_COPY_AND_ASSIGN(FakeStream);
16266};
16267
16268// Fake HttpStreamRequest that simply records calls to SetPriority()
16269// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4716270class FakeStreamRequest : public HttpStreamRequest,
16271 public base::SupportsWeakPtr<FakeStreamRequest> {
16272 public:
[email protected]e86839fd2013-08-14 18:29:0316273 FakeStreamRequest(RequestPriority priority,
16274 HttpStreamRequest::Delegate* delegate)
16275 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4416276 delegate_(delegate),
16277 websocket_stream_create_helper_(NULL) {}
16278
16279 FakeStreamRequest(RequestPriority priority,
16280 HttpStreamRequest::Delegate* delegate,
16281 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
16282 : priority_(priority),
16283 delegate_(delegate),
16284 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0316285
Chris Watkins7a41d3552017-12-01 02:13:2716286 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4716287
16288 RequestPriority priority() const { return priority_; }
16289
[email protected]831e4a32013-11-14 02:14:4416290 const WebSocketHandshakeStreamBase::CreateHelper*
16291 websocket_stream_create_helper() const {
16292 return websocket_stream_create_helper_;
16293 }
16294
[email protected]e86839fd2013-08-14 18:29:0316295 // Create a new FakeStream and pass it to the request's
16296 // delegate. Returns a weak pointer to the FakeStream.
16297 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1916298 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0316299 // Do this before calling OnStreamReady() as OnStreamReady() may
16300 // immediately delete |fake_stream|.
16301 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0016302 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0316303 return weak_stream;
16304 }
16305
asanka681f02d2017-02-22 17:06:3916306 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4716307 ADD_FAILURE();
16308 return ERR_UNEXPECTED;
16309 }
16310
dchengb03027d2014-10-21 12:00:2016311 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4716312 ADD_FAILURE();
16313 return LoadState();
16314 }
16315
dchengb03027d2014-10-21 12:00:2016316 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4716317
bnc94c92842016-09-21 15:22:5216318 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716319
bnc6227b26e2016-08-12 02:00:4316320 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4716321
dchengb03027d2014-10-21 12:00:2016322 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4716323
ttuttle1f2d7e92015-04-28 16:17:4716324 const ConnectionAttempts& connection_attempts() const override {
16325 static ConnectionAttempts no_attempts;
16326 return no_attempts;
16327 }
16328
[email protected]bf828982013-08-14 18:01:4716329 private:
16330 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0316331 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4416332 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4716333
16334 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
16335};
16336
16337// Fake HttpStreamFactory that vends FakeStreamRequests.
16338class FakeStreamFactory : public HttpStreamFactory {
16339 public:
Chris Watkins7a41d3552017-12-01 02:13:2716340 FakeStreamFactory() = default;
16341 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4716342
16343 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
16344 // RequestStream() (which may be NULL if it was destroyed already).
16345 base::WeakPtr<FakeStreamRequest> last_stream_request() {
16346 return last_stream_request_;
16347 }
16348
xunjieli96f2a402017-06-05 17:24:2716349 std::unique_ptr<HttpStreamRequest> RequestStream(
16350 const HttpRequestInfo& info,
16351 RequestPriority priority,
16352 const SSLConfig& server_ssl_config,
16353 const SSLConfig& proxy_ssl_config,
16354 HttpStreamRequest::Delegate* delegate,
16355 bool enable_ip_based_pooling,
16356 bool enable_alternative_services,
16357 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1916358 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4716359 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716360 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716361 }
16362
xunjieli96f2a402017-06-05 17:24:2716363 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0816364 const HttpRequestInfo& info,
16365 RequestPriority priority,
16366 const SSLConfig& server_ssl_config,
16367 const SSLConfig& proxy_ssl_config,
16368 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2916369 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616370 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016371 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0816372 NOTREACHED();
16373 return nullptr;
16374 }
16375
xunjieli96f2a402017-06-05 17:24:2716376 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4716377 const HttpRequestInfo& info,
16378 RequestPriority priority,
16379 const SSLConfig& server_ssl_config,
16380 const SSLConfig& proxy_ssl_config,
16381 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4616382 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2916383 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2616384 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2016385 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2716386 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1916387 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4416388 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2716389 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4716390 }
16391
dchengb03027d2014-10-21 12:00:2016392 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5916393 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4716394 ADD_FAILURE();
16395 }
16396
dchengb03027d2014-10-21 12:00:2016397 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4716398 ADD_FAILURE();
16399 return NULL;
16400 }
16401
xunjielif5267de2017-01-20 21:18:5716402 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
16403 const std::string& parent_absolute_name) const override {
16404 ADD_FAILURE();
16405 }
16406
[email protected]bf828982013-08-14 18:01:4716407 private:
16408 base::WeakPtr<FakeStreamRequest> last_stream_request_;
16409
16410 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
16411};
16412
[email protected]bf828982013-08-14 18:01:4716413} // namespace
16414
16415// Make sure that HttpNetworkTransaction passes on its priority to its
16416// stream request on start.
bncd16676a2016-07-20 16:23:0116417TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216419 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716420 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916421 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716422
krasinc06a72a2016-12-21 03:42:4616423 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116424 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716425
Ramin Halavatib5e433e2018-02-07 07:41:1016426 request.traffic_annotation =
16427 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16428
wezca1070932016-05-26 20:30:5216429 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716430
[email protected]bf828982013-08-14 18:01:4716431 TestCompletionCallback callback;
16432 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016433 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716434
16435 base::WeakPtr<FakeStreamRequest> fake_request =
16436 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216437 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716438 EXPECT_EQ(LOW, fake_request->priority());
16439}
16440
16441// Make sure that HttpNetworkTransaction passes on its priority
16442// updates to its stream request.
bncd16676a2016-07-20 16:23:0116443TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916444 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216445 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716446 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916447 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716448
krasinc06a72a2016-12-21 03:42:4616449 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116450 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716451
Ramin Halavatib5e433e2018-02-07 07:41:1016452 request.traffic_annotation =
16453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16454
[email protected]bf828982013-08-14 18:01:4716455 TestCompletionCallback callback;
16456 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016457 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716458
16459 base::WeakPtr<FakeStreamRequest> fake_request =
16460 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216461 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716462 EXPECT_EQ(LOW, fake_request->priority());
16463
16464 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216465 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716466 EXPECT_EQ(LOWEST, fake_request->priority());
16467}
16468
[email protected]e86839fd2013-08-14 18:29:0316469// Make sure that HttpNetworkTransaction passes on its priority
16470// updates to its stream.
bncd16676a2016-07-20 16:23:0116471TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216473 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316474 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916475 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316476
krasinc06a72a2016-12-21 03:42:4616477 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116478 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316479
Ramin Halavatib5e433e2018-02-07 07:41:1016480 request.traffic_annotation =
16481 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
16482
[email protected]e86839fd2013-08-14 18:29:0316483 TestCompletionCallback callback;
16484 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016485 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316486
16487 base::WeakPtr<FakeStreamRequest> fake_request =
16488 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216489 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316490 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216491 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316492 EXPECT_EQ(LOW, fake_stream->priority());
16493
16494 trans.SetPriority(LOWEST);
16495 EXPECT_EQ(LOWEST, fake_stream->priority());
16496}
16497
[email protected]043b68c82013-08-22 23:41:5216498// Tests that when a used socket is returned to the SSL socket pool, it's closed
16499// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116500TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216501 ClientSocketPoolManager::set_max_sockets_per_group(
16502 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16503 ClientSocketPoolManager::set_max_sockets_per_pool(
16504 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16505
16506 // Set up SSL request.
16507
16508 HttpRequestInfo ssl_request;
16509 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316510 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016511 ssl_request.traffic_annotation =
16512 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216513
16514 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316515 MockWrite(
16516 "GET / HTTP/1.1\r\n"
16517 "Host: www.example.org\r\n"
16518 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216519 };
16520 MockRead ssl_reads[] = {
16521 MockRead("HTTP/1.1 200 OK\r\n"),
16522 MockRead("Content-Length: 11\r\n\r\n"),
16523 MockRead("hello world"),
16524 MockRead(SYNCHRONOUS, OK),
16525 };
16526 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16527 ssl_writes, arraysize(ssl_writes));
16528 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16529
16530 SSLSocketDataProvider ssl(ASYNC, OK);
16531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16532
16533 // Set up HTTP request.
16534
16535 HttpRequestInfo http_request;
16536 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316537 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016538 http_request.traffic_annotation =
16539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216540
16541 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316542 MockWrite(
16543 "GET / HTTP/1.1\r\n"
16544 "Host: www.example.org\r\n"
16545 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216546 };
16547 MockRead http_reads[] = {
16548 MockRead("HTTP/1.1 200 OK\r\n"),
16549 MockRead("Content-Length: 7\r\n\r\n"),
16550 MockRead("falafel"),
16551 MockRead(SYNCHRONOUS, OK),
16552 };
16553 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16554 http_writes, arraysize(http_writes));
16555 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16556
danakj1fd259a02016-04-16 03:17:0916557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216558
16559 // Start the SSL request.
16560 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616561 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016562 ASSERT_EQ(ERR_IO_PENDING,
16563 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16564 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216565
16566 // Start the HTTP request. Pool should stall.
16567 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616568 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016569 ASSERT_EQ(ERR_IO_PENDING,
16570 http_trans.Start(&http_request, http_callback.callback(),
16571 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116572 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216573
16574 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116575 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216576 std::string response_data;
bnc691fda62016-08-12 00:43:1616577 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216578 EXPECT_EQ("hello world", response_data);
16579
16580 // The SSL socket should automatically be closed, so the HTTP request can
16581 // start.
dcheng48459ac22014-08-26 00:46:4116582 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16583 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216584
16585 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116586 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616587 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216588 EXPECT_EQ("falafel", response_data);
16589
dcheng48459ac22014-08-26 00:46:4116590 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216591}
16592
16593// Tests that when a SSL connection is established but there's no corresponding
16594// request that needs it, the new socket is closed if the transport socket pool
16595// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116596TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216597 ClientSocketPoolManager::set_max_sockets_per_group(
16598 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16599 ClientSocketPoolManager::set_max_sockets_per_pool(
16600 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16601
16602 // Set up an ssl request.
16603
16604 HttpRequestInfo ssl_request;
16605 ssl_request.method = "GET";
16606 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1016607 ssl_request.traffic_annotation =
16608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216609
16610 // No data will be sent on the SSL socket.
16611 StaticSocketDataProvider ssl_data;
16612 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16613
16614 SSLSocketDataProvider ssl(ASYNC, OK);
16615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16616
16617 // Set up HTTP request.
16618
16619 HttpRequestInfo http_request;
16620 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316621 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016622 http_request.traffic_annotation =
16623 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216624
16625 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316626 MockWrite(
16627 "GET / HTTP/1.1\r\n"
16628 "Host: www.example.org\r\n"
16629 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216630 };
16631 MockRead http_reads[] = {
16632 MockRead("HTTP/1.1 200 OK\r\n"),
16633 MockRead("Content-Length: 7\r\n\r\n"),
16634 MockRead("falafel"),
16635 MockRead(SYNCHRONOUS, OK),
16636 };
16637 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16638 http_writes, arraysize(http_writes));
16639 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16640
danakj1fd259a02016-04-16 03:17:0916641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216642
16643 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16644 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916645 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916646 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116647 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216648
16649 // Start the HTTP request. Pool should stall.
16650 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616651 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016652 ASSERT_EQ(ERR_IO_PENDING,
16653 http_trans.Start(&http_request, http_callback.callback(),
16654 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116655 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216656
16657 // The SSL connection will automatically be closed once the connection is
16658 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116659 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216660 std::string response_data;
bnc691fda62016-08-12 00:43:1616661 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216662 EXPECT_EQ("falafel", response_data);
16663
dcheng48459ac22014-08-26 00:46:4116664 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216665}
16666
bncd16676a2016-07-20 16:23:0116667TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916668 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216669 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916670 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216671 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416672
16673 HttpRequestInfo request;
16674 request.method = "POST";
16675 request.url = GURL("http://www.foo.com/");
16676 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016677 request.traffic_annotation =
16678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416679
danakj1fd259a02016-04-16 03:17:0916680 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616681 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416682 // Send headers successfully, but get an error while sending the body.
16683 MockWrite data_writes[] = {
16684 MockWrite("POST / HTTP/1.1\r\n"
16685 "Host: www.foo.com\r\n"
16686 "Connection: keep-alive\r\n"
16687 "Content-Length: 3\r\n\r\n"),
16688 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16689 };
16690
16691 MockRead data_reads[] = {
16692 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16693 MockRead("hello world"),
16694 MockRead(SYNCHRONOUS, OK),
16695 };
16696 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16697 arraysize(data_writes));
16698 session_deps_.socket_factory->AddSocketDataProvider(&data);
16699
16700 TestCompletionCallback callback;
16701
tfarina42834112016-09-22 13:38:2016702 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416704
16705 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116706 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416707
bnc691fda62016-08-12 00:43:1616708 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216709 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416710
wezca1070932016-05-26 20:30:5216711 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416712 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16713
16714 std::string response_data;
bnc691fda62016-08-12 00:43:1616715 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116716 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416717 EXPECT_EQ("hello world", response_data);
16718}
16719
16720// This test makes sure the retry logic doesn't trigger when reading an error
16721// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116722TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416723 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416725 MockWrite data_writes[] = {
16726 MockWrite("GET / HTTP/1.1\r\n"
16727 "Host: www.foo.com\r\n"
16728 "Connection: keep-alive\r\n\r\n"),
16729 MockWrite("POST / HTTP/1.1\r\n"
16730 "Host: www.foo.com\r\n"
16731 "Connection: keep-alive\r\n"
16732 "Content-Length: 3\r\n\r\n"),
16733 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16734 };
16735
16736 MockRead data_reads[] = {
16737 MockRead("HTTP/1.1 200 Peachy\r\n"
16738 "Content-Length: 14\r\n\r\n"),
16739 MockRead("first response"),
16740 MockRead("HTTP/1.1 400 Not OK\r\n"
16741 "Content-Length: 15\r\n\r\n"),
16742 MockRead("second response"),
16743 MockRead(SYNCHRONOUS, OK),
16744 };
16745 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16746 arraysize(data_writes));
16747 session_deps_.socket_factory->AddSocketDataProvider(&data);
16748
16749 TestCompletionCallback callback;
16750 HttpRequestInfo request1;
16751 request1.method = "GET";
16752 request1.url = GURL("http://www.foo.com/");
16753 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016754 request1.traffic_annotation =
16755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416756
bnc87dcefc2017-05-25 12:47:5816757 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916758 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016759 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416761
16762 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116763 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416764
16765 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216766 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416767
wezca1070932016-05-26 20:30:5216768 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416769 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16770
16771 std::string response_data1;
16772 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116773 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416774 EXPECT_EQ("first response", response_data1);
16775 // Delete the transaction to release the socket back into the socket pool.
16776 trans1.reset();
16777
danakj1fd259a02016-04-16 03:17:0916778 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216779 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916780 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216781 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416782
16783 HttpRequestInfo request2;
16784 request2.method = "POST";
16785 request2.url = GURL("http://www.foo.com/");
16786 request2.upload_data_stream = &upload_data_stream;
16787 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016788 request2.traffic_annotation =
16789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416790
bnc691fda62016-08-12 00:43:1616791 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016792 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416794
16795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116796 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416797
bnc691fda62016-08-12 00:43:1616798 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216799 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416800
wezca1070932016-05-26 20:30:5216801 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416802 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16803
16804 std::string response_data2;
bnc691fda62016-08-12 00:43:1616805 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116806 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416807 EXPECT_EQ("second response", response_data2);
16808}
16809
bncd16676a2016-07-20 16:23:0116810TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416811 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916812 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216813 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916814 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216815 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416816
16817 HttpRequestInfo request;
16818 request.method = "POST";
16819 request.url = GURL("http://www.foo.com/");
16820 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016821 request.traffic_annotation =
16822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416823
danakj1fd259a02016-04-16 03:17:0916824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616825 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416826 // Send headers successfully, but get an error while sending the body.
16827 MockWrite data_writes[] = {
16828 MockWrite("POST / HTTP/1.1\r\n"
16829 "Host: www.foo.com\r\n"
16830 "Connection: keep-alive\r\n"
16831 "Content-Length: 3\r\n\r\n"
16832 "fo"),
16833 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16834 };
16835
16836 MockRead data_reads[] = {
16837 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16838 MockRead("hello world"),
16839 MockRead(SYNCHRONOUS, OK),
16840 };
16841 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16842 arraysize(data_writes));
16843 session_deps_.socket_factory->AddSocketDataProvider(&data);
16844
16845 TestCompletionCallback callback;
16846
tfarina42834112016-09-22 13:38:2016847 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416849
16850 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116851 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416852
bnc691fda62016-08-12 00:43:1616853 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216854 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416855
wezca1070932016-05-26 20:30:5216856 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416857 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16858
16859 std::string response_data;
bnc691fda62016-08-12 00:43:1616860 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116861 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416862 EXPECT_EQ("hello world", response_data);
16863}
16864
16865// This tests the more common case than the previous test, where headers and
16866// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116867TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716868 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416869
16870 HttpRequestInfo request;
16871 request.method = "POST";
16872 request.url = GURL("http://www.foo.com/");
16873 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016874 request.traffic_annotation =
16875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416876
danakj1fd259a02016-04-16 03:17:0916877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416879 // Send headers successfully, but get an error while sending the body.
16880 MockWrite data_writes[] = {
16881 MockWrite("POST / HTTP/1.1\r\n"
16882 "Host: www.foo.com\r\n"
16883 "Connection: keep-alive\r\n"
16884 "Transfer-Encoding: chunked\r\n\r\n"),
16885 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16886 };
16887
16888 MockRead data_reads[] = {
16889 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16890 MockRead("hello world"),
16891 MockRead(SYNCHRONOUS, OK),
16892 };
16893 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16894 arraysize(data_writes));
16895 session_deps_.socket_factory->AddSocketDataProvider(&data);
16896
16897 TestCompletionCallback callback;
16898
tfarina42834112016-09-22 13:38:2016899 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416901 // Make sure the headers are sent before adding a chunk. This ensures that
16902 // they can't be merged with the body in a single send. Not currently
16903 // necessary since a chunked body is never merged with headers, but this makes
16904 // the test more future proof.
16905 base::RunLoop().RunUntilIdle();
16906
mmenkecbc2b712014-10-09 20:29:0716907 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416908
16909 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116910 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416911
bnc691fda62016-08-12 00:43:1616912 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216913 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416914
wezca1070932016-05-26 20:30:5216915 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416916 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16917
16918 std::string response_data;
bnc691fda62016-08-12 00:43:1616919 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116920 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416921 EXPECT_EQ("hello world", response_data);
16922}
16923
bncd16676a2016-07-20 16:23:0116924TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916925 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216926 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916927 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216928 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416929
16930 HttpRequestInfo request;
16931 request.method = "POST";
16932 request.url = GURL("http://www.foo.com/");
16933 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016934 request.traffic_annotation =
16935 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416936
danakj1fd259a02016-04-16 03:17:0916937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416939
16940 MockWrite data_writes[] = {
16941 MockWrite("POST / HTTP/1.1\r\n"
16942 "Host: www.foo.com\r\n"
16943 "Connection: keep-alive\r\n"
16944 "Content-Length: 3\r\n\r\n"),
16945 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16946 };
16947
16948 MockRead data_reads[] = {
16949 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16950 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16951 MockRead("hello world"),
16952 MockRead(SYNCHRONOUS, OK),
16953 };
16954 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16955 arraysize(data_writes));
16956 session_deps_.socket_factory->AddSocketDataProvider(&data);
16957
16958 TestCompletionCallback callback;
16959
tfarina42834112016-09-22 13:38:2016960 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416962
16963 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116964 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416965
bnc691fda62016-08-12 00:43:1616966 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216967 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416968
wezca1070932016-05-26 20:30:5216969 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416970 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16971
16972 std::string response_data;
bnc691fda62016-08-12 00:43:1616973 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116974 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416975 EXPECT_EQ("hello world", response_data);
16976}
16977
bncd16676a2016-07-20 16:23:0116978TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916979 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216980 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916981 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216982 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416983
16984 HttpRequestInfo request;
16985 request.method = "POST";
16986 request.url = GURL("http://www.foo.com/");
16987 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016988 request.traffic_annotation =
16989 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416990
danakj1fd259a02016-04-16 03:17:0916991 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416993 // Send headers successfully, but get an error while sending the body.
16994 MockWrite data_writes[] = {
16995 MockWrite("POST / HTTP/1.1\r\n"
16996 "Host: www.foo.com\r\n"
16997 "Connection: keep-alive\r\n"
16998 "Content-Length: 3\r\n\r\n"),
16999 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17000 };
17001
17002 MockRead data_reads[] = {
17003 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17004 MockRead("hello world"),
17005 MockRead(SYNCHRONOUS, OK),
17006 };
17007 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17008 arraysize(data_writes));
17009 session_deps_.socket_factory->AddSocketDataProvider(&data);
17010
17011 TestCompletionCallback callback;
17012
tfarina42834112016-09-22 13:38:2017013 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417015
17016 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117017 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417018}
17019
bncd16676a2016-07-20 16:23:0117020TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417021 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917022 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217023 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917024 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217025 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417026
17027 HttpRequestInfo request;
17028 request.method = "POST";
17029 request.url = GURL("http://www.foo.com/");
17030 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017031 request.traffic_annotation =
17032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417033
danakj1fd259a02016-04-16 03:17:0917034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417036 // Send headers successfully, but get an error while sending the body.
17037 MockWrite data_writes[] = {
17038 MockWrite("POST / HTTP/1.1\r\n"
17039 "Host: www.foo.com\r\n"
17040 "Connection: keep-alive\r\n"
17041 "Content-Length: 3\r\n\r\n"),
17042 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17043 };
17044
17045 MockRead data_reads[] = {
17046 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17047 MockRead("HTTP/1.0 302 Redirect\r\n"),
17048 MockRead("Location: http://somewhere-else.com/\r\n"),
17049 MockRead("Content-Length: 0\r\n\r\n"),
17050 MockRead(SYNCHRONOUS, OK),
17051 };
17052 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17053 arraysize(data_writes));
17054 session_deps_.socket_factory->AddSocketDataProvider(&data);
17055
17056 TestCompletionCallback callback;
17057
tfarina42834112016-09-22 13:38:2017058 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417060
17061 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117062 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417063}
17064
bncd16676a2016-07-20 16:23:0117065TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917066 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217067 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917068 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217069 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417070
17071 HttpRequestInfo request;
17072 request.method = "POST";
17073 request.url = GURL("http://www.foo.com/");
17074 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017075 request.traffic_annotation =
17076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417077
danakj1fd259a02016-04-16 03:17:0917078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417080 // Send headers successfully, but get an error while sending the body.
17081 MockWrite data_writes[] = {
17082 MockWrite("POST / HTTP/1.1\r\n"
17083 "Host: www.foo.com\r\n"
17084 "Connection: keep-alive\r\n"
17085 "Content-Length: 3\r\n\r\n"),
17086 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17087 };
17088
17089 MockRead data_reads[] = {
17090 MockRead("HTTP 0.9 rocks!"),
17091 MockRead(SYNCHRONOUS, OK),
17092 };
17093 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17094 arraysize(data_writes));
17095 session_deps_.socket_factory->AddSocketDataProvider(&data);
17096
17097 TestCompletionCallback callback;
17098
tfarina42834112016-09-22 13:38:2017099 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117100 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417101
17102 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117103 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417104}
17105
bncd16676a2016-07-20 16:23:0117106TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917107 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217108 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917109 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217110 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417111
17112 HttpRequestInfo request;
17113 request.method = "POST";
17114 request.url = GURL("http://www.foo.com/");
17115 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017116 request.traffic_annotation =
17117 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417118
danakj1fd259a02016-04-16 03:17:0917119 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617120 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417121 // Send headers successfully, but get an error while sending the body.
17122 MockWrite data_writes[] = {
17123 MockWrite("POST / HTTP/1.1\r\n"
17124 "Host: www.foo.com\r\n"
17125 "Connection: keep-alive\r\n"
17126 "Content-Length: 3\r\n\r\n"),
17127 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17128 };
17129
17130 MockRead data_reads[] = {
17131 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17132 MockRead(SYNCHRONOUS, OK),
17133 };
17134 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17135 arraysize(data_writes));
17136 session_deps_.socket_factory->AddSocketDataProvider(&data);
17137
17138 TestCompletionCallback callback;
17139
tfarina42834112016-09-22 13:38:2017140 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117141 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417142
17143 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117144 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417145}
17146
Bence Békydca6bd92018-01-30 13:43:0617147#if BUILDFLAG(ENABLE_WEBSOCKETS)
17148
17149namespace {
17150
17151void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17152 headers->SetHeader("Connection", "Upgrade");
17153 headers->SetHeader("Upgrade", "websocket");
17154 headers->SetHeader("Origin", "http://www.example.org");
17155 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617156}
17157
17158} // namespace
17159
17160TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
17161 // The same logic needs to be tested for both ws: and wss: schemes, but this
17162 // test is already parameterised on NextProto, so it uses a loop to verify
17163 // that the different schemes work.
17164 std::string test_cases[] = {"ws://www.example.org/",
17165 "wss://www.example.org/"};
17166 for (size_t i = 0; i < arraysize(test_cases); ++i) {
17167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17168 HttpNetworkSessionPeer peer(session.get());
17169 FakeStreamFactory* fake_factory = new FakeStreamFactory();
17170 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
17171
17172 HttpRequestInfo request;
17173 request.method = "GET";
17174 request.url = GURL(test_cases[i]);
Ramin Halavatib5e433e2018-02-07 07:41:1017175 request.traffic_annotation =
17176 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617177
Bence Béky8d1c6052018-02-07 12:48:1517178 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17179
Bence Békydca6bd92018-01-30 13:43:0617180 HttpNetworkTransaction trans(LOW, session.get());
17181 trans.SetWebSocketHandshakeStreamCreateHelper(
17182 &websocket_stream_create_helper);
17183
17184 TestCompletionCallback callback;
17185 EXPECT_EQ(ERR_IO_PENDING,
17186 trans.Start(&request, callback.callback(), NetLogWithSource()));
17187
17188 base::WeakPtr<FakeStreamRequest> fake_request =
17189 fake_factory->last_stream_request();
17190 ASSERT_TRUE(fake_request);
17191 EXPECT_EQ(&websocket_stream_create_helper,
17192 fake_request->websocket_stream_create_helper());
17193 }
17194}
17195
Adam Rice425cf122015-01-19 06:18:2417196// Verify that proxy headers are not sent to the destination server when
17197// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117198TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417199 HttpRequestInfo request;
17200 request.method = "GET";
bncce36dca22015-04-21 22:11:2317201 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017202 request.traffic_annotation =
17203 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417204 AddWebSocketHeaders(&request.extra_headers);
17205
17206 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917207 session_deps_.proxy_resolution_service =
17208 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2417209
danakj1fd259a02016-04-16 03:17:0917210 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417211
17212 // Since a proxy is configured, try to establish a tunnel.
17213 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717214 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17215 "Host: www.example.org:443\r\n"
17216 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417217
17218 // After calling trans->RestartWithAuth(), this is the request we should
17219 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717220 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17221 "Host: www.example.org:443\r\n"
17222 "Proxy-Connection: keep-alive\r\n"
17223 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417224
rsleevidb16bb02015-11-12 23:47:1717225 MockWrite("GET / HTTP/1.1\r\n"
17226 "Host: www.example.org\r\n"
17227 "Connection: Upgrade\r\n"
17228 "Upgrade: websocket\r\n"
17229 "Origin: http://www.example.org\r\n"
17230 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517231 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17232 "Sec-WebSocket-Extensions: permessage-deflate; "
17233 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417234
17235 // The proxy responds to the connect with a 407, using a persistent
17236 // connection.
17237 MockRead data_reads[] = {
17238 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517239 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17240 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17241 "Content-Length: 0\r\n"
17242 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417243
17244 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17245
Bence Béky8d1c6052018-02-07 12:48:1517246 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17247 "Upgrade: websocket\r\n"
17248 "Connection: Upgrade\r\n"
17249 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417250
17251 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17252 arraysize(data_writes));
17253 session_deps_.socket_factory->AddSocketDataProvider(&data);
17254 SSLSocketDataProvider ssl(ASYNC, OK);
17255 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17256
Bence Béky8d1c6052018-02-07 12:48:1517257 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17258
bnc87dcefc2017-05-25 12:47:5817259 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917260 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417261 trans->SetWebSocketHandshakeStreamCreateHelper(
17262 &websocket_stream_create_helper);
17263
17264 {
17265 TestCompletionCallback callback;
17266
tfarina42834112016-09-22 13:38:2017267 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417269
17270 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117271 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417272 }
17273
17274 const HttpResponseInfo* response = trans->GetResponseInfo();
17275 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217276 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417277 EXPECT_EQ(407, response->headers->response_code());
17278
17279 {
17280 TestCompletionCallback callback;
17281
17282 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17283 callback.callback());
robpercival214763f2016-07-01 23:27:0117284 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417285
17286 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117287 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417288 }
17289
17290 response = trans->GetResponseInfo();
17291 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217292 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417293
17294 EXPECT_EQ(101, response->headers->response_code());
17295
17296 trans.reset();
17297 session->CloseAllConnections();
17298}
17299
17300// Verify that proxy headers are not sent to the destination server when
17301// establishing a tunnel for an insecure WebSocket connection.
17302// This requires the authentication info to be injected into the auth cache
17303// due to crbug.com/395064
17304// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117305TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417306 HttpRequestInfo request;
17307 request.method = "GET";
bncce36dca22015-04-21 22:11:2317308 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017309 request.traffic_annotation =
17310 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417311 AddWebSocketHeaders(&request.extra_headers);
17312
17313 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917314 session_deps_.proxy_resolution_service =
17315 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2417316
danakj1fd259a02016-04-16 03:17:0917317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417318
17319 MockWrite data_writes[] = {
17320 // Try to establish a tunnel for the WebSocket connection, with
17321 // credentials. Because WebSockets have a separate set of socket pools,
17322 // they cannot and will not use the same TCP/IP connection as the
17323 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517324 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17325 "Host: www.example.org:80\r\n"
17326 "Proxy-Connection: keep-alive\r\n"
17327 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417328
Bence Béky8d1c6052018-02-07 12:48:1517329 MockWrite("GET / HTTP/1.1\r\n"
17330 "Host: www.example.org\r\n"
17331 "Connection: Upgrade\r\n"
17332 "Upgrade: websocket\r\n"
17333 "Origin: http://www.example.org\r\n"
17334 "Sec-WebSocket-Version: 13\r\n"
17335 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17336 "Sec-WebSocket-Extensions: permessage-deflate; "
17337 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417338
17339 MockRead data_reads[] = {
17340 // HTTP CONNECT with credentials.
17341 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17342
17343 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517344 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17345 "Upgrade: websocket\r\n"
17346 "Connection: Upgrade\r\n"
17347 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417348
17349 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17350 arraysize(data_writes));
17351 session_deps_.socket_factory->AddSocketDataProvider(&data);
17352
17353 session->http_auth_cache()->Add(
17354 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17355 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17356
Bence Béky8d1c6052018-02-07 12:48:1517357 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17358
bnc87dcefc2017-05-25 12:47:5817359 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917360 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417361 trans->SetWebSocketHandshakeStreamCreateHelper(
17362 &websocket_stream_create_helper);
17363
17364 TestCompletionCallback callback;
17365
tfarina42834112016-09-22 13:38:2017366 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417368
17369 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117370 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417371
17372 const HttpResponseInfo* response = trans->GetResponseInfo();
17373 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217374 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417375
17376 EXPECT_EQ(101, response->headers->response_code());
17377
17378 trans.reset();
17379 session->CloseAllConnections();
17380}
17381
Bence Békydca6bd92018-01-30 13:43:0617382#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17383
bncd16676a2016-07-20 16:23:0117384TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917385 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217386 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917387 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217388 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217389
17390 HttpRequestInfo request;
17391 request.method = "POST";
17392 request.url = GURL("http://www.foo.com/");
17393 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017394 request.traffic_annotation =
17395 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217396
danakj1fd259a02016-04-16 03:17:0917397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617398 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217399 MockWrite data_writes[] = {
17400 MockWrite("POST / HTTP/1.1\r\n"
17401 "Host: www.foo.com\r\n"
17402 "Connection: keep-alive\r\n"
17403 "Content-Length: 3\r\n\r\n"),
17404 MockWrite("foo"),
17405 };
17406
17407 MockRead data_reads[] = {
17408 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17409 MockRead(SYNCHRONOUS, OK),
17410 };
17411 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17412 arraysize(data_writes));
17413 session_deps_.socket_factory->AddSocketDataProvider(&data);
17414
17415 TestCompletionCallback callback;
17416
17417 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017418 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117419 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217420
17421 std::string response_data;
bnc691fda62016-08-12 00:43:1617422 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217423
17424 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617425 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217426 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617427 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217428}
17429
bncd16676a2016-07-20 16:23:0117430TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917431 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217432 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917433 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217434 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217435
17436 HttpRequestInfo request;
17437 request.method = "POST";
17438 request.url = GURL("http://www.foo.com/");
17439 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017440 request.traffic_annotation =
17441 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217442
danakj1fd259a02016-04-16 03:17:0917443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217445 MockWrite data_writes[] = {
17446 MockWrite("POST / HTTP/1.1\r\n"
17447 "Host: www.foo.com\r\n"
17448 "Connection: keep-alive\r\n"
17449 "Content-Length: 3\r\n\r\n"),
17450 MockWrite("foo"),
17451 };
17452
17453 MockRead data_reads[] = {
17454 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17455 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17456 MockRead(SYNCHRONOUS, OK),
17457 };
17458 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17459 arraysize(data_writes));
17460 session_deps_.socket_factory->AddSocketDataProvider(&data);
17461
17462 TestCompletionCallback callback;
17463
17464 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017465 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117466 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217467
17468 std::string response_data;
bnc691fda62016-08-12 00:43:1617469 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217470
17471 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617472 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217473 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617474 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217475}
17476
bncd16676a2016-07-20 16:23:0117477TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217478 ChunkedUploadDataStream upload_data_stream(0);
17479
17480 HttpRequestInfo request;
17481 request.method = "POST";
17482 request.url = GURL("http://www.foo.com/");
17483 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017484 request.traffic_annotation =
17485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217486
danakj1fd259a02016-04-16 03:17:0917487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217489 // Send headers successfully, but get an error while sending the body.
17490 MockWrite data_writes[] = {
17491 MockWrite("POST / HTTP/1.1\r\n"
17492 "Host: www.foo.com\r\n"
17493 "Connection: keep-alive\r\n"
17494 "Transfer-Encoding: chunked\r\n\r\n"),
17495 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17496 };
17497
17498 MockRead data_reads[] = {
17499 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17500 MockRead(SYNCHRONOUS, OK),
17501 };
17502 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17503 arraysize(data_writes));
17504 session_deps_.socket_factory->AddSocketDataProvider(&data);
17505
17506 TestCompletionCallback callback;
17507
17508 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017509 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217510
17511 base::RunLoop().RunUntilIdle();
17512 upload_data_stream.AppendData("f", 1, false);
17513
17514 base::RunLoop().RunUntilIdle();
17515 upload_data_stream.AppendData("oo", 2, true);
17516
robpercival214763f2016-07-01 23:27:0117517 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217518
17519 std::string response_data;
bnc691fda62016-08-12 00:43:1617520 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217521
17522 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617523 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217524 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617525 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217526}
17527
rdsmith1d343be52016-10-21 20:37:5017528// Confirm that transactions whose throttle is created in (and stays in)
17529// the unthrottled state are not blocked.
17530TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17531 TestNetworkStreamThrottler* throttler(nullptr);
17532 std::unique_ptr<HttpNetworkSession> session(
17533 CreateSessionWithThrottler(&session_deps_, &throttler));
17534
17535 // Send a simple request and make sure it goes through.
17536 HttpRequestInfo request;
17537 request.method = "GET";
17538 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017539 request.traffic_annotation =
17540 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017541
bnc87dcefc2017-05-25 12:47:5817542 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917543 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017544
17545 MockWrite data_writes[] = {
17546 MockWrite("GET / HTTP/1.1\r\n"
17547 "Host: www.example.org\r\n"
17548 "Connection: keep-alive\r\n\r\n"),
17549 };
17550 MockRead data_reads[] = {
17551 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17552 MockRead(SYNCHRONOUS, OK),
17553 };
17554 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17555 arraysize(data_writes));
17556 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17557
17558 TestCompletionCallback callback;
17559 trans->Start(&request, callback.callback(), NetLogWithSource());
17560 EXPECT_EQ(OK, callback.WaitForResult());
17561}
17562
17563// Confirm requests can be blocked by a throttler, and are resumed
17564// when the throttle is unblocked.
17565TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17566 TestNetworkStreamThrottler* throttler(nullptr);
17567 std::unique_ptr<HttpNetworkSession> session(
17568 CreateSessionWithThrottler(&session_deps_, &throttler));
17569
17570 // Send a simple request and make sure it goes through.
17571 HttpRequestInfo request;
17572 request.method = "GET";
17573 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017574 request.traffic_annotation =
17575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017576
17577 MockWrite data_writes[] = {
17578 MockWrite("GET / HTTP/1.1\r\n"
17579 "Host: www.example.org\r\n"
17580 "Connection: keep-alive\r\n\r\n"),
17581 };
17582 MockRead data_reads[] = {
17583 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17584 MockRead(SYNCHRONOUS, OK),
17585 };
17586 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17587 arraysize(data_writes));
17588 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17589
17590 // Start a request that will be throttled at start; confirm it
17591 // doesn't complete.
17592 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817593 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917594 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017595
17596 TestCompletionCallback callback;
17597 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17598 EXPECT_EQ(ERR_IO_PENDING, rv);
17599
17600 base::RunLoop().RunUntilIdle();
17601 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17602 EXPECT_FALSE(callback.have_result());
17603
17604 // Confirm the request goes on to complete when unthrottled.
17605 throttler->UnthrottleAllRequests();
17606 base::RunLoop().RunUntilIdle();
17607 ASSERT_TRUE(callback.have_result());
17608 EXPECT_EQ(OK, callback.WaitForResult());
17609}
17610
17611// Destroy a request while it's throttled.
17612TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17613 TestNetworkStreamThrottler* throttler(nullptr);
17614 std::unique_ptr<HttpNetworkSession> session(
17615 CreateSessionWithThrottler(&session_deps_, &throttler));
17616
17617 // Send a simple request and make sure it goes through.
17618 HttpRequestInfo request;
17619 request.method = "GET";
17620 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017621 request.traffic_annotation =
17622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017623
17624 MockWrite data_writes[] = {
17625 MockWrite("GET / HTTP/1.1\r\n"
17626 "Host: www.example.org\r\n"
17627 "Connection: keep-alive\r\n\r\n"),
17628 };
17629 MockRead data_reads[] = {
17630 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17631 MockRead(SYNCHRONOUS, OK),
17632 };
17633 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17634 arraysize(data_writes));
17635 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17636
17637 // Start a request that will be throttled at start; confirm it
17638 // doesn't complete.
17639 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817640 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917641 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017642
17643 TestCompletionCallback callback;
17644 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17645 EXPECT_EQ(ERR_IO_PENDING, rv);
17646
17647 base::RunLoop().RunUntilIdle();
17648 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17649 EXPECT_FALSE(callback.have_result());
17650
17651 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17652 trans.reset();
17653 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17654}
17655
17656// Confirm the throttler receives SetPriority calls.
17657TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17658 TestNetworkStreamThrottler* throttler(nullptr);
17659 std::unique_ptr<HttpNetworkSession> session(
17660 CreateSessionWithThrottler(&session_deps_, &throttler));
17661
17662 // Send a simple request and make sure it goes through.
17663 HttpRequestInfo request;
17664 request.method = "GET";
17665 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017666 request.traffic_annotation =
17667 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017668
17669 MockWrite data_writes[] = {
17670 MockWrite("GET / HTTP/1.1\r\n"
17671 "Host: www.example.org\r\n"
17672 "Connection: keep-alive\r\n\r\n"),
17673 };
17674 MockRead data_reads[] = {
17675 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17676 MockRead(SYNCHRONOUS, OK),
17677 };
17678 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17679 arraysize(data_writes));
17680 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17681
17682 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917683 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017684 // Start the transaction to associate a throttle with it.
17685 TestCompletionCallback callback;
17686 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17687 EXPECT_EQ(ERR_IO_PENDING, rv);
17688
17689 EXPECT_EQ(0, throttler->num_set_priority_calls());
17690 trans->SetPriority(LOW);
17691 EXPECT_EQ(1, throttler->num_set_priority_calls());
17692 EXPECT_EQ(LOW, throttler->last_priority_set());
17693
17694 throttler->UnthrottleAllRequests();
17695 base::RunLoop().RunUntilIdle();
17696 ASSERT_TRUE(callback.have_result());
17697 EXPECT_EQ(OK, callback.WaitForResult());
17698}
17699
17700// Confirm that unthrottling from a SetPriority call by the
17701// throttler works properly.
17702TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17703 TestNetworkStreamThrottler* throttler(nullptr);
17704 std::unique_ptr<HttpNetworkSession> session(
17705 CreateSessionWithThrottler(&session_deps_, &throttler));
17706
17707 // Send a simple request and make sure it goes through.
17708 HttpRequestInfo request;
17709 request.method = "GET";
17710 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017711 request.traffic_annotation =
17712 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017713
17714 MockWrite data_writes[] = {
17715 MockWrite("GET / HTTP/1.1\r\n"
17716 "Host: www.example.org\r\n"
17717 "Connection: keep-alive\r\n\r\n"),
17718 };
17719 MockRead data_reads[] = {
17720 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17721 MockRead(SYNCHRONOUS, OK),
17722 };
17723 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17724 arraysize(data_writes));
17725 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17726
17727 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17728 data_writes, arraysize(data_writes));
17729 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17730
17731 // Start a request that will be throttled at start; confirm it
17732 // doesn't complete.
17733 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817734 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917735 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017736
17737 TestCompletionCallback callback;
17738 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17739 EXPECT_EQ(ERR_IO_PENDING, rv);
17740
17741 base::RunLoop().RunUntilIdle();
17742 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17743 EXPECT_FALSE(callback.have_result());
17744
17745 // Create a new request, call SetPriority on it to unthrottle,
17746 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917747 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017748 throttler->set_priority_change_closure(
17749 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17750 base::Unretained(throttler)));
17751
17752 // Start the transaction to associate a throttle with it.
17753 TestCompletionCallback callback1;
17754 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17755 EXPECT_EQ(ERR_IO_PENDING, rv);
17756
17757 trans1->SetPriority(IDLE);
17758
17759 base::RunLoop().RunUntilIdle();
17760 ASSERT_TRUE(callback.have_result());
17761 EXPECT_EQ(OK, callback.WaitForResult());
17762 ASSERT_TRUE(callback1.have_result());
17763 EXPECT_EQ(OK, callback1.WaitForResult());
17764}
17765
17766// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817767void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017768
17769// Confirm that destroying a transaction from a SetPriority call by the
17770// throttler works properly.
17771TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17772 TestNetworkStreamThrottler* throttler(nullptr);
17773 std::unique_ptr<HttpNetworkSession> session(
17774 CreateSessionWithThrottler(&session_deps_, &throttler));
17775
17776 // Send a simple request and make sure it goes through.
17777 HttpRequestInfo request;
17778 request.method = "GET";
17779 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017780 request.traffic_annotation =
17781 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rdsmith1d343be52016-10-21 20:37:5017782
17783 MockWrite data_writes[] = {
17784 MockWrite("GET / HTTP/1.1\r\n"
17785 "Host: www.example.org\r\n"
17786 "Connection: keep-alive\r\n\r\n"),
17787 };
17788 MockRead data_reads[] = {
17789 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17790 MockRead(SYNCHRONOUS, OK),
17791 };
17792 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17793 arraysize(data_writes));
17794 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17795
17796 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17797 data_writes, arraysize(data_writes));
17798 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17799
17800 // Start a request that will be throttled at start; confirm it
17801 // doesn't complete.
17802 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817803 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917804 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017805
17806 TestCompletionCallback callback;
17807 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17808 EXPECT_EQ(ERR_IO_PENDING, rv);
17809
17810 base::RunLoop().RunUntilIdle();
17811 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17812 EXPECT_FALSE(callback.have_result());
17813
17814 // Arrange for the set priority call on the above transaction to delete
17815 // the transaction.
bnc87dcefc2017-05-25 12:47:5817816 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017817 throttler->set_priority_change_closure(
17818 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17819
17820 // Call it and check results (partially a "doesn't crash" test).
17821 trans_ptr->SetPriority(IDLE);
17822 trans_ptr = nullptr; // No longer a valid pointer.
17823
17824 base::RunLoop().RunUntilIdle();
17825 ASSERT_FALSE(callback.have_result());
17826}
17827
nharperb7441ef2016-01-25 23:54:1417828#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117829TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417830 const std::string https_url = "https://www.example.com";
17831 HttpRequestInfo request;
17832 request.url = GURL(https_url);
17833 request.method = "GET";
Ramin Halavatib5e433e2018-02-07 07:41:1017834 request.traffic_annotation =
17835 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417836
17837 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917838 ssl.ssl_info.token_binding_negotiated = true;
17839 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617840 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417841 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17842
bnc42331402016-07-25 13:36:1517843 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117844 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17845 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417846 MockRead(ASYNC, ERR_IO_PENDING)};
17847 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17848 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817849 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917850 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417852
17853 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17854 TestCompletionCallback callback;
17855 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017856 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017857
17858 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417859
17860 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17861 HttpRequestHeaders headers;
17862 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17863 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17864}
17865#endif // !defined(OS_IOS)
17866
eustasc7d27da2017-04-06 10:33:2017867void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17868 const std::string& accept_encoding,
17869 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317870 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017871 bool should_match) {
17872 HttpRequestInfo request;
17873 request.method = "GET";
17874 request.url = GURL("http://www.foo.com/");
17875 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17876 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017877 request.traffic_annotation =
17878 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017879
17880 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17882 // Send headers successfully, but get an error while sending the body.
17883 MockWrite data_writes[] = {
17884 MockWrite("GET / HTTP/1.1\r\n"
17885 "Host: www.foo.com\r\n"
17886 "Connection: keep-alive\r\n"
17887 "Accept-Encoding: "),
17888 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17889 };
17890
sky50576f32017-05-01 19:28:0317891 std::string response_code = "200 OK";
17892 std::string extra;
17893 if (!location.empty()) {
17894 response_code = "301 Redirect\r\nLocation: ";
17895 response_code.append(location);
17896 }
17897
eustasc7d27da2017-04-06 10:33:2017898 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317899 MockRead("HTTP/1.0 "),
17900 MockRead(response_code.data()),
17901 MockRead("\r\nContent-Encoding: "),
17902 MockRead(content_encoding.data()),
17903 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017904 MockRead(SYNCHRONOUS, OK),
17905 };
17906 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17907 arraysize(data_writes));
17908 session_deps->socket_factory->AddSocketDataProvider(&data);
17909
17910 TestCompletionCallback callback;
17911
17912 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17914
17915 rv = callback.WaitForResult();
17916 if (should_match) {
17917 EXPECT_THAT(rv, IsOk());
17918 } else {
17919 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17920 }
17921}
17922
17923TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317924 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017925}
17926
17927TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317928 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17929 true);
eustasc7d27da2017-04-06 10:33:2017930}
17931
17932TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17933 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317934 "", false);
17935}
17936
17937TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17938 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17939 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017940}
17941
xunjieli96f2a402017-06-05 17:24:2717942TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17943 ProxyConfig proxy_config;
17944 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17945 proxy_config.set_pac_mandatory(true);
17946 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917947 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Jeremy Roman0579ed62017-08-29 15:56:1917948 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417949 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717950
17951 HttpRequestInfo request;
17952 request.method = "GET";
17953 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017954 request.traffic_annotation =
17955 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717956
17957 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17958 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17959
17960 TestCompletionCallback callback;
17961
17962 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17964 EXPECT_THAT(callback.WaitForResult(),
17965 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17966}
17967
17968TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17969 ProxyConfig proxy_config;
17970 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17971 proxy_config.set_pac_mandatory(true);
17972 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17973 new MockAsyncProxyResolverFactory(false);
17974 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917975 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
17976 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
17977 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717978 HttpRequestInfo request;
17979 request.method = "GET";
17980 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017981 request.traffic_annotation =
17982 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717983
17984 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17986
17987 TestCompletionCallback callback;
17988 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17990
17991 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17992 ERR_FAILED, &resolver);
17993 EXPECT_THAT(callback.WaitForResult(),
17994 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17995}
17996
17997TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917998 session_deps_.proxy_resolution_service =
17999 ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
xunjieli96f2a402017-06-05 17:24:2718000 session_deps_.enable_quic = false;
18001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18002
18003 HttpRequestInfo request;
18004 request.method = "GET";
18005 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018006 request.traffic_annotation =
18007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718008
18009 TestCompletionCallback callback;
18010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18011 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18013
18014 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18015}
18016
[email protected]89ceba9a2009-03-21 03:46:0618017} // namespace net