blob: 3fd6552fb39d1b94b0ddae0db021238067b11093 [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/");
initial.commit586acc5fe2008-07-26 22:42:52463
vishal.b62985ca92015-04-17 08:45:51464 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07465 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09466 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27468
[email protected]5a60c8b2011-10-19 20:14:29469 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07470 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29471 }
initial.commit586acc5fe2008-07-26 22:42:52472
[email protected]49639fa2011-12-20 23:22:41473 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52474
eroman24bc6a12015-05-06 19:55:48475 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16476 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52478
[email protected]ff007e162009-05-23 09:13:15479 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16480 out.total_received_bytes = trans.GetTotalReceivedBytes();
481 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25482
483 // Even in the failure cases that use this function, connections are always
484 // successfully established before the error.
bnc691fda62016-08-12 00:43:16485 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25486 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
487
[email protected]ff007e162009-05-23 09:13:15488 if (out.rv != OK)
489 return out;
490
bnc691fda62016-08-12 00:43:16491 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50492 // Can't use ASSERT_* inside helper functions like this, so
493 // return an error.
wezca1070932016-05-26 20:30:52494 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50495 out.rv = ERR_UNEXPECTED;
496 return out;
497 }
[email protected]ff007e162009-05-23 09:13:15498 out.status_line = response->headers->GetStatusLine();
499
[email protected]80a09a82012-11-16 17:40:06500 EXPECT_EQ("127.0.0.1", response->socket_address.host());
501 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19502
ttuttled9dbc652015-09-29 20:00:59503 bool got_endpoint =
bnc691fda62016-08-12 00:43:16504 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59505 EXPECT_EQ(got_endpoint,
506 out.remote_endpoint_after_start.address().size() > 0);
507
bnc691fda62016-08-12 00:43:16508 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01509 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40510
mmenke43758e62015-05-04 21:09:46511 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40512 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39513 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00514 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
515 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39516 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00517 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
518 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15519
[email protected]f3da152d2012-06-02 01:00:57520 std::string line;
521 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
522 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
523
[email protected]79e1fd62013-06-20 06:50:04524 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16525 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04526 std::string value;
527 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23528 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04529 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
530 EXPECT_EQ("keep-alive", value);
531
532 std::string response_headers;
533 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23534 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04535 response_headers);
[email protected]3deb9a52010-11-11 00:24:40536
bnc691fda62016-08-12 00:43:16537 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22538 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16539 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22540
bnc691fda62016-08-12 00:43:16541 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47542 return out;
[email protected]ff007e162009-05-23 09:13:15543 }
initial.commit586acc5fe2008-07-26 22:42:52544
[email protected]5a60c8b2011-10-19 20:14:29545 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
546 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22547 MockWrite data_writes[] = {
548 MockWrite("GET / HTTP/1.1\r\n"
549 "Host: www.example.org\r\n"
550 "Connection: keep-alive\r\n\r\n"),
551 };
[email protected]5a60c8b2011-10-19 20:14:29552
sclittlefb249892015-09-10 21:33:22553 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
554 arraysize(data_writes));
555 StaticSocketDataProvider* data[] = {&reads};
556 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
557
558 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
559 out.total_sent_bytes);
560 return out;
[email protected]b8015c42013-12-24 15:18:19561 }
562
bnc032658ba2016-09-26 18:17:15563 void AddSSLSocketData() {
564 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49565 ssl_.ssl_info.cert =
566 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
567 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15568 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
569 }
570
[email protected]ff007e162009-05-23 09:13:15571 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
572 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52573
[email protected]ff007e162009-05-23 09:13:15574 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07575
576 void BypassHostCacheOnRefreshHelper(int load_flags);
577
578 void CheckErrorIsPassedBack(int error, IoMode mode);
579
[email protected]4bd46222013-05-14 19:32:23580 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07581 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15582 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03583
584 // Original socket limits. Some tests set these. Safest to always restore
585 // them once each test has been run.
586 int old_max_group_sockets_;
587 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15588};
[email protected]231d5a32008-09-13 00:45:27589
[email protected]448d4ca52012-03-04 04:12:23590namespace {
591
ryansturm49a8cb12016-06-15 16:51:09592class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27593 public:
ryansturm49a8cb12016-06-15 16:51:09594 BeforeHeadersSentHandler()
595 : observed_before_headers_sent_with_proxy_(false),
596 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27597
ryansturm49a8cb12016-06-15 16:51:09598 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
599 HttpRequestHeaders* request_headers) {
600 observed_before_headers_sent_ = true;
601 if (!proxy_info.is_http() && !proxy_info.is_https() &&
602 !proxy_info.is_quic()) {
603 return;
604 }
605 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27606 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
607 }
608
ryansturm49a8cb12016-06-15 16:51:09609 bool observed_before_headers_sent_with_proxy() const {
610 return observed_before_headers_sent_with_proxy_;
611 }
612
613 bool observed_before_headers_sent() const {
614 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27615 }
616
617 std::string observed_proxy_server_uri() const {
618 return observed_proxy_server_uri_;
619 }
620
621 private:
ryansturm49a8cb12016-06-15 16:51:09622 bool observed_before_headers_sent_with_proxy_;
623 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27624 std::string observed_proxy_server_uri_;
625
ryansturm49a8cb12016-06-15 16:51:09626 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27627};
628
[email protected]15a5ccf82008-10-23 19:57:43629// Fill |str| with a long header list that consumes >= |size| bytes.
630void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51631 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19632 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
633 const int sizeof_row = strlen(row);
634 const int num_rows = static_cast<int>(
635 ceil(static_cast<float>(size) / sizeof_row));
636 const int sizeof_data = num_rows * sizeof_row;
637 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43638 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51639
[email protected]4ddaf2502008-10-23 18:26:19640 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43641 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19642}
643
thakis84dff942015-07-28 20:47:38644#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09645uint64_t MockGetMSTime() {
646 // Tue, 23 May 2017 20:13:07 +0000
647 return 131400439870000000;
648}
649
[email protected]385a4672009-03-11 22:21:29650// Alternative functions that eliminate randomness and dependency on the local
651// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37652void MockGenerateRandom(uint8_t* output, size_t n) {
653 // This is set to 0xaa because the client challenge for testing in
654 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
655 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29656}
657
[email protected]fe2bc6a2009-03-23 16:52:20658std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37659 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29660}
thakis84dff942015-07-28 20:47:38661#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29662
[email protected]e60e47a2010-07-14 03:37:18663template<typename ParentPool>
664class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31665 public:
[email protected]9e1bdd32011-02-03 21:48:34666 CaptureGroupNameSocketPool(HostResolver* host_resolver,
667 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18668
[email protected]d80a4322009-08-14 07:07:49669 const std::string last_group_name_received() const {
670 return last_group_name_;
671 }
672
Tarun Bansal162eabe52018-01-20 01:16:39673 bool socket_requested() const { return socket_requested_; }
674
dmichaeld6e570d2014-12-18 22:30:57675 int RequestSocket(const std::string& group_name,
676 const void* socket_params,
677 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54678 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15679 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57680 ClientSocketHandle* handle,
681 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20682 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31683 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39684 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31685 return ERR_IO_PENDING;
686 }
dmichaeld6e570d2014-12-18 22:30:57687 void CancelRequest(const std::string& group_name,
688 ClientSocketHandle* handle) override {}
689 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09690 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57691 int id) override {}
692 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23693 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57694 int IdleSocketCount() const override { return 0; }
695 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31696 return 0;
697 }
dmichaeld6e570d2014-12-18 22:30:57698 LoadState GetLoadState(const std::string& group_name,
699 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31700 return LOAD_STATE_IDLE;
701 }
dmichaeld6e570d2014-12-18 22:30:57702 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26703 return base::TimeDelta();
704 }
[email protected]d80a4322009-08-14 07:07:49705
706 private:
[email protected]04e5be32009-06-26 20:00:31707 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39708 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31709};
710
[email protected]ab739042011-04-07 15:22:28711typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
712CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13713typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
714CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06715typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11716CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18717typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
718CaptureGroupNameSSLSocketPool;
719
rkaplowd90695c2015-03-25 22:12:41720template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18721CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34722 HostResolver* host_resolver,
723 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21724 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18725
hashimoto0d3e4fb2015-01-09 05:02:50726template <>
[email protected]2df19bb2010-08-25 20:13:46727CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21728 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34729 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09730 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46731
[email protected]007b3f82013-04-09 08:46:45732template <>
[email protected]e60e47a2010-07-14 03:37:18733CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21734 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34735 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45736 : SSLClientSocketPool(0,
737 0,
[email protected]007b3f82013-04-09 08:46:45738 cert_verifier,
739 NULL,
740 NULL,
[email protected]284303b62013-11-28 15:11:54741 NULL,
eranm6571b2b2014-12-03 15:53:23742 NULL,
[email protected]007b3f82013-04-09 08:46:45743 std::string(),
744 NULL,
745 NULL,
746 NULL,
747 NULL,
748 NULL,
[email protected]8e458552014-08-05 00:02:15749 NULL) {
750}
[email protected]2227c692010-05-04 15:36:11751
[email protected]231d5a32008-09-13 00:45:27752//-----------------------------------------------------------------------------
753
[email protected]79cb5c12011-09-12 13:12:04754// Helper functions for validating that AuthChallengeInfo's are correctly
755// configured for common cases.
756bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
757 if (!auth_challenge)
758 return false;
759 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43760 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04761 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19762 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04763 return true;
764}
765
766bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
767 if (!auth_challenge)
768 return false;
769 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43770 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
771 EXPECT_EQ("MyRealm1", auth_challenge->realm);
772 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
773 return true;
774}
775
776bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
777 if (!auth_challenge)
778 return false;
779 EXPECT_TRUE(auth_challenge->is_proxy);
780 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04781 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19782 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04783 return true;
784}
785
786bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
787 if (!auth_challenge)
788 return false;
789 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43790 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04791 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19792 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04793 return true;
794}
795
thakis84dff942015-07-28 20:47:38796#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04797bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
798 if (!auth_challenge)
799 return false;
800 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55801 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04802 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19803 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04804 return true;
805}
thakis84dff942015-07-28 20:47:38806#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04807
[email protected]448d4ca52012-03-04 04:12:23808} // namespace
809
bncd16676a2016-07-20 16:23:01810TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27813}
814
bncd16676a2016-07-20 16:23:01815TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27816 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35817 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
818 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06819 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27820 };
[email protected]31a2bfe2010-02-09 08:03:39821 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
822 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01823 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27824 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
825 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22826 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
827 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47828 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59829
830 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27831}
832
833// Response with no status line.
bncd16676a2016-07-20 16:23:01834TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27835 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35836 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06837 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27838 };
[email protected]31a2bfe2010-02-09 08:03:39839 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
840 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41841 EXPECT_THAT(out.rv, IsOk());
842 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
843 EXPECT_EQ("hello world", out.response_data);
844 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
845 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27846}
847
mmenkea7da6da2016-09-01 21:56:52848// Response with no status line, and a weird port. Should fail by default.
849TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
850 MockRead data_reads[] = {
851 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
852 };
853
854 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
855 session_deps_.socket_factory->AddSocketDataProvider(&data);
856
857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
858
krasinc06a72a2016-12-21 03:42:46859 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58860 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19861 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52862
mmenkea7da6da2016-09-01 21:56:52863 request.method = "GET";
864 request.url = GURL("http://www.example.com:2000/");
865 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20866 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52867 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
868}
869
Shivani Sharmafdcaefd2017-11-02 00:12:26870// Tests that request info can be destroyed after the headers phase is complete.
871TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
872 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
873 auto trans =
874 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
875
876 MockRead data_reads[] = {
877 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
878 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
879 };
880 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
881 session_deps_.socket_factory->AddSocketDataProvider(&data);
882
883 TestCompletionCallback callback;
884
885 {
886 auto request = std::make_unique<HttpRequestInfo>();
887 request->method = "GET";
888 request->url = GURL("http://www.example.org/");
889
890 int rv =
891 trans->Start(request.get(), callback.callback(), NetLogWithSource());
892
893 EXPECT_THAT(callback.GetResult(rv), IsOk());
894 } // Let request info be destroyed.
895
896 trans.reset();
897}
898
mmenkea7da6da2016-09-01 21:56:52899// Response with no status line, and a weird port. Option to allow weird ports
900// enabled.
901TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
902 MockRead data_reads[] = {
903 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
904 };
905
906 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
907 session_deps_.socket_factory->AddSocketDataProvider(&data);
908 session_deps_.http_09_on_non_default_ports_enabled = true;
909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
910
krasinc06a72a2016-12-21 03:42:46911 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58912 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19913 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52914
mmenkea7da6da2016-09-01 21:56:52915 request.method = "GET";
916 request.url = GURL("http://www.example.com:2000/");
917 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20918 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52919 EXPECT_THAT(callback.GetResult(rv), IsOk());
920
921 const HttpResponseInfo* info = trans->GetResponseInfo();
922 ASSERT_TRUE(info->headers);
923 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
924
925 // Don't bother to read the body - that's verified elsewhere, important thing
926 // is that the option to allow HTTP/0.9 on non-default ports is respected.
927}
928
[email protected]231d5a32008-09-13 00:45:27929// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01930TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27931 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35932 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06933 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27934 };
[email protected]31a2bfe2010-02-09 08:03:39935 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
936 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01937 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27938 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
939 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22940 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
941 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27942}
943
944// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01945TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27946 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35947 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06948 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27949 };
[email protected]31a2bfe2010-02-09 08:03:39950 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
951 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01952 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27953 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
954 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22955 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
956 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27957}
958
959// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01960TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27961 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35962 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06963 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27964 };
[email protected]31a2bfe2010-02-09 08:03:39965 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
966 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41967 EXPECT_THAT(out.rv, IsOk());
968 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
969 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
970 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
971 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27972}
973
974// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01975TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27976 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35977 MockRead("\n"),
978 MockRead("\n"),
979 MockRead("Q"),
980 MockRead("J"),
981 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06982 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27983 };
[email protected]31a2bfe2010-02-09 08:03:39984 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
985 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01986 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27987 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
988 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22989 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
990 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27991}
992
993// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01994TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27995 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35996 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06997 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27998 };
[email protected]31a2bfe2010-02-09 08:03:39999 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1000 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:411001 EXPECT_THAT(out.rv, IsOk());
1002 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
1003 EXPECT_EQ("HTT", out.response_data);
1004 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1005 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:521006}
1007
[email protected]f9d44aa2008-09-23 23:57:171008// Simulate a 204 response, lacking a Content-Length header, sent over a
1009// persistent connection. The response should still terminate since a 204
1010// cannot have a response body.
bncd16676a2016-07-20 16:23:011011TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:191012 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171013 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351014 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191015 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061016 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171017 };
[email protected]31a2bfe2010-02-09 08:03:391018 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1019 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011020 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171021 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1022 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221023 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1024 int64_t response_size = reads_size - strlen(junk);
1025 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171026}
1027
[email protected]0877e3d2009-10-17 22:29:571028// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011029TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191030 std::string final_chunk = "0\r\n\r\n";
1031 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1032 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571033 MockRead data_reads[] = {
1034 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1035 MockRead("5\r\nHello\r\n"),
1036 MockRead("1\r\n"),
1037 MockRead(" \r\n"),
1038 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191039 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061040 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571041 };
[email protected]31a2bfe2010-02-09 08:03:391042 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1043 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011044 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571045 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1046 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221047 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1048 int64_t response_size = reads_size - extra_data.size();
1049 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571050}
1051
[email protected]9fe44f52010-09-23 18:36:001052// Next tests deal with http://crbug.com/56344.
1053
bncd16676a2016-07-20 16:23:011054TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001055 MultipleContentLengthHeadersNoTransferEncoding) {
1056 MockRead data_reads[] = {
1057 MockRead("HTTP/1.1 200 OK\r\n"),
1058 MockRead("Content-Length: 10\r\n"),
1059 MockRead("Content-Length: 5\r\n\r\n"),
1060 };
1061 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1062 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011063 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001064}
1065
bncd16676a2016-07-20 16:23:011066TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041067 DuplicateContentLengthHeadersNoTransferEncoding) {
1068 MockRead data_reads[] = {
1069 MockRead("HTTP/1.1 200 OK\r\n"),
1070 MockRead("Content-Length: 5\r\n"),
1071 MockRead("Content-Length: 5\r\n\r\n"),
1072 MockRead("Hello"),
1073 };
1074 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1075 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011076 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041077 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1078 EXPECT_EQ("Hello", out.response_data);
1079}
1080
bncd16676a2016-07-20 16:23:011081TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041082 ComplexContentLengthHeadersNoTransferEncoding) {
1083 // More than 2 dupes.
1084 {
1085 MockRead data_reads[] = {
1086 MockRead("HTTP/1.1 200 OK\r\n"),
1087 MockRead("Content-Length: 5\r\n"),
1088 MockRead("Content-Length: 5\r\n"),
1089 MockRead("Content-Length: 5\r\n\r\n"),
1090 MockRead("Hello"),
1091 };
1092 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1093 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011094 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041095 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1096 EXPECT_EQ("Hello", out.response_data);
1097 }
1098 // HTTP/1.0
1099 {
1100 MockRead data_reads[] = {
1101 MockRead("HTTP/1.0 200 OK\r\n"),
1102 MockRead("Content-Length: 5\r\n"),
1103 MockRead("Content-Length: 5\r\n"),
1104 MockRead("Content-Length: 5\r\n\r\n"),
1105 MockRead("Hello"),
1106 };
1107 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1108 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011109 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041110 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1111 EXPECT_EQ("Hello", out.response_data);
1112 }
1113 // 2 dupes and one mismatched.
1114 {
1115 MockRead data_reads[] = {
1116 MockRead("HTTP/1.1 200 OK\r\n"),
1117 MockRead("Content-Length: 10\r\n"),
1118 MockRead("Content-Length: 10\r\n"),
1119 MockRead("Content-Length: 5\r\n\r\n"),
1120 };
1121 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1122 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011123 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041124 }
1125}
1126
bncd16676a2016-07-20 16:23:011127TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001128 MultipleContentLengthHeadersTransferEncoding) {
1129 MockRead data_reads[] = {
1130 MockRead("HTTP/1.1 200 OK\r\n"),
1131 MockRead("Content-Length: 666\r\n"),
1132 MockRead("Content-Length: 1337\r\n"),
1133 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1134 MockRead("5\r\nHello\r\n"),
1135 MockRead("1\r\n"),
1136 MockRead(" \r\n"),
1137 MockRead("5\r\nworld\r\n"),
1138 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061139 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001140 };
1141 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1142 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011143 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001144 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1145 EXPECT_EQ("Hello world", out.response_data);
1146}
1147
[email protected]1628fe92011-10-04 23:04:551148// Next tests deal with http://crbug.com/98895.
1149
1150// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011151TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551152 MockRead data_reads[] = {
1153 MockRead("HTTP/1.1 200 OK\r\n"),
1154 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1155 MockRead("Content-Length: 5\r\n\r\n"),
1156 MockRead("Hello"),
1157 };
1158 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1159 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011160 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551161 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1162 EXPECT_EQ("Hello", out.response_data);
1163}
1164
[email protected]54a9c6e52012-03-21 20:10:591165// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011166TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551167 MockRead data_reads[] = {
1168 MockRead("HTTP/1.1 200 OK\r\n"),
1169 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1170 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1171 MockRead("Content-Length: 5\r\n\r\n"),
1172 MockRead("Hello"),
1173 };
1174 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1175 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011176 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591177 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1178 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551179}
1180
1181// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011182TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551183 MockRead data_reads[] = {
1184 MockRead("HTTP/1.1 200 OK\r\n"),
1185 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1186 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1187 MockRead("Content-Length: 5\r\n\r\n"),
1188 MockRead("Hello"),
1189 };
1190 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1191 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011192 EXPECT_THAT(out.rv,
1193 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551194}
1195
[email protected]54a9c6e52012-03-21 20:10:591196// Checks that two identical Location headers result in no error.
1197// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011198TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551199 MockRead data_reads[] = {
1200 MockRead("HTTP/1.1 302 Redirect\r\n"),
1201 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591202 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551203 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061204 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551205 };
1206
1207 HttpRequestInfo request;
1208 request.method = "GET";
1209 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551210
danakj1fd259a02016-04-16 03:17:091211 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551213
1214 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071215 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551216
[email protected]49639fa2011-12-20 23:22:411217 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551218
tfarina42834112016-09-22 13:38:201219 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551221
robpercival214763f2016-07-01 23:27:011222 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551223
bnc691fda62016-08-12 00:43:161224 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521225 ASSERT_TRUE(response);
1226 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551227 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1228 std::string url;
1229 EXPECT_TRUE(response->headers->IsRedirect(&url));
1230 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471231 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551232}
1233
[email protected]1628fe92011-10-04 23:04:551234// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011235TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551236 MockRead data_reads[] = {
1237 MockRead("HTTP/1.1 302 Redirect\r\n"),
1238 MockRead("Location: http://good.com/\r\n"),
1239 MockRead("Location: http://evil.com/\r\n"),
1240 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061241 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551242 };
1243 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1244 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011245 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551246}
1247
[email protected]ef0faf2e72009-03-05 23:27:231248// Do a request using the HEAD method. Verify that we don't try to read the
1249// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011250TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421251 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231252 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231253 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231254
danakj1fd259a02016-04-16 03:17:091255 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161256 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091257 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161258 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091259 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1260 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271261
[email protected]ef0faf2e72009-03-05 23:27:231262 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131263 MockWrite("HEAD / HTTP/1.1\r\n"
1264 "Host: www.example.org\r\n"
1265 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231266 };
1267 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231268 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1269 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231270
mmenked39192ee2015-12-09 00:57:231271 // No response body because the test stops reading here.
1272 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231273 };
1274
[email protected]31a2bfe2010-02-09 08:03:391275 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1276 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071277 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231278
[email protected]49639fa2011-12-20 23:22:411279 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231280
tfarina42834112016-09-22 13:38:201281 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231283
1284 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011285 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231286
bnc691fda62016-08-12 00:43:161287 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521288 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231289
1290 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521291 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231292 EXPECT_EQ(1234, response->headers->GetContentLength());
1293 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471294 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091295 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1296 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231297
1298 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101299 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231300 bool has_server_header = response->headers->EnumerateHeader(
1301 &iter, "Server", &server_header);
1302 EXPECT_TRUE(has_server_header);
1303 EXPECT_EQ("Blah", server_header);
1304
1305 // Reading should give EOF right away, since there is no message body
1306 // (despite non-zero content-length).
1307 std::string response_data;
bnc691fda62016-08-12 00:43:161308 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011309 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231310 EXPECT_EQ("", response_data);
1311}
1312
bncd16676a2016-07-20 16:23:011313TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091314 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521315
1316 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351317 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1318 MockRead("hello"),
1319 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1320 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061321 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521322 };
[email protected]31a2bfe2010-02-09 08:03:391323 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071324 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521325
[email protected]0b0bf032010-09-21 18:08:501326 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521327 "hello", "world"
1328 };
1329
1330 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421331 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521332 request.method = "GET";
bncce36dca22015-04-21 22:11:231333 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521334
bnc691fda62016-08-12 00:43:161335 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271336
[email protected]49639fa2011-12-20 23:22:411337 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521338
tfarina42834112016-09-22 13:38:201339 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521341
1342 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011343 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521344
bnc691fda62016-08-12 00:43:161345 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521346 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521347
wezca1070932016-05-26 20:30:521348 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251349 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471350 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521351
1352 std::string response_data;
bnc691fda62016-08-12 00:43:161353 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011354 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251355 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521356 }
1357}
1358
bncd16676a2016-07-20 16:23:011359TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091360 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221361 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191362 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221363 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271364
[email protected]1c773ea12009-04-28 19:58:421365 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521366 request.method = "POST";
1367 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271368 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521369
shivanishab9a143952016-09-19 17:23:411370 // Check the upload progress returned before initialization is correct.
1371 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1372 EXPECT_EQ(0u, progress.size());
1373 EXPECT_EQ(0u, progress.position());
1374
danakj1fd259a02016-04-16 03:17:091375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271377
initial.commit586acc5fe2008-07-26 22:42:521378 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351379 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1380 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1381 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061382 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521383 };
[email protected]31a2bfe2010-02-09 08:03:391384 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071385 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521386
[email protected]49639fa2011-12-20 23:22:411387 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521388
tfarina42834112016-09-22 13:38:201389 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521391
1392 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011393 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521394
bnc691fda62016-08-12 00:43:161395 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521396 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521397
wezca1070932016-05-26 20:30:521398 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251399 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521400
1401 std::string response_data;
bnc691fda62016-08-12 00:43:161402 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011403 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251404 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521405}
1406
[email protected]3a2d3662009-03-27 03:49:141407// This test is almost the same as Ignores100 above, but the response contains
1408// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571409// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011410TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421411 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141412 request.method = "GET";
1413 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141414
danakj1fd259a02016-04-16 03:17:091415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271417
[email protected]3a2d3662009-03-27 03:49:141418 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571419 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1420 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141421 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061422 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141423 };
[email protected]31a2bfe2010-02-09 08:03:391424 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071425 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141426
[email protected]49639fa2011-12-20 23:22:411427 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141428
tfarina42834112016-09-22 13:38:201429 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141431
1432 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011433 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141434
bnc691fda62016-08-12 00:43:161435 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521436 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141437
wezca1070932016-05-26 20:30:521438 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141439 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1440
1441 std::string response_data;
bnc691fda62016-08-12 00:43:161442 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011443 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141444 EXPECT_EQ("hello world", response_data);
1445}
1446
bncd16676a2016-07-20 16:23:011447TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081448 HttpRequestInfo request;
1449 request.method = "POST";
1450 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081451
danakj1fd259a02016-04-16 03:17:091452 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161453 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081454
1455 MockRead data_reads[] = {
1456 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1457 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381458 };
zmo9528c9f42015-08-04 22:12:081459 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1460 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381461
zmo9528c9f42015-08-04 22:12:081462 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381463
tfarina42834112016-09-22 13:38:201464 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381466
zmo9528c9f42015-08-04 22:12:081467 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011468 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381469
zmo9528c9f42015-08-04 22:12:081470 std::string response_data;
bnc691fda62016-08-12 00:43:161471 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011472 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081473 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381474}
1475
bncd16676a2016-07-20 16:23:011476TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381477 HttpRequestInfo request;
1478 request.method = "POST";
1479 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381480
danakj1fd259a02016-04-16 03:17:091481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271483
[email protected]ee9410e72010-01-07 01:42:381484 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061485 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381486 };
[email protected]31a2bfe2010-02-09 08:03:391487 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071488 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381489
[email protected]49639fa2011-12-20 23:22:411490 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381491
tfarina42834112016-09-22 13:38:201492 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381494
1495 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011496 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381497}
1498
[email protected]23e482282013-06-14 16:08:021499void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511500 const MockWrite* write_failure,
1501 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421502 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521503 request.method = "GET";
1504 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521505
vishal.b62985ca92015-04-17 08:45:511506 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071507 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091508 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271509
[email protected]202965992011-12-07 23:04:511510 // Written data for successfully sending both requests.
1511 MockWrite data1_writes[] = {
1512 MockWrite("GET / HTTP/1.1\r\n"
1513 "Host: www.foo.com\r\n"
1514 "Connection: keep-alive\r\n\r\n"),
1515 MockWrite("GET / HTTP/1.1\r\n"
1516 "Host: www.foo.com\r\n"
1517 "Connection: keep-alive\r\n\r\n")
1518 };
1519
1520 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521521 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351522 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1523 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061524 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521525 };
[email protected]202965992011-12-07 23:04:511526
1527 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491528 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511529 data1_writes[1] = *write_failure;
1530 } else {
1531 ASSERT_TRUE(read_failure);
1532 data1_reads[2] = *read_failure;
1533 }
1534
1535 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1536 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071537 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521538
1539 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351540 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1541 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061542 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521543 };
[email protected]31a2bfe2010-02-09 08:03:391544 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071545 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521546
thestig9d3bb0c2015-01-24 00:49:511547 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521548 "hello", "world"
1549 };
1550
mikecironef22f9812016-10-04 03:40:191551 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521552 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411553 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521554
bnc691fda62016-08-12 00:43:161555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521556
tfarina42834112016-09-22 13:38:201557 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521559
1560 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011561 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521562
[email protected]58e32bb2013-01-21 18:23:251563 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161564 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251565 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1566 if (i == 0) {
1567 first_socket_log_id = load_timing_info.socket_log_id;
1568 } else {
1569 // The second request should be using a new socket.
1570 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1571 }
1572
bnc691fda62016-08-12 00:43:161573 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521574 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521575
wezca1070932016-05-26 20:30:521576 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471577 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251578 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521579
1580 std::string response_data;
bnc691fda62016-08-12 00:43:161581 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011582 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251583 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521584 }
1585}
[email protected]3d2a59b2008-09-26 19:44:251586
[email protected]a34f61ee2014-03-18 20:59:491587void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1588 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101589 const MockRead* read_failure,
1590 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491591 HttpRequestInfo request;
1592 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101593 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491594
vishal.b62985ca92015-04-17 08:45:511595 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491596 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491598
[email protected]09356c652014-03-25 15:36:101599 SSLSocketDataProvider ssl1(ASYNC, OK);
1600 SSLSocketDataProvider ssl2(ASYNC, OK);
1601 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361602 ssl1.next_proto = kProtoHTTP2;
1603 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101604 }
1605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491607
[email protected]09356c652014-03-25 15:36:101608 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411609 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491610 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411611 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151612 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411613 SpdySerializedFrame spdy_data(
1614 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491615
[email protected]09356c652014-03-25 15:36:101616 // HTTP/1.1 versions of the request and response.
1617 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1618 "Host: www.foo.com\r\n"
1619 "Connection: keep-alive\r\n\r\n";
1620 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1621 const char kHttpData[] = "hello";
1622
1623 std::vector<MockRead> data1_reads;
1624 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491625 if (write_failure) {
1626 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101627 data1_writes.push_back(*write_failure);
1628 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491629 } else {
1630 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101631 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411632 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101633 } else {
1634 data1_writes.push_back(MockWrite(kHttpRequest));
1635 }
1636 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491637 }
1638
[email protected]09356c652014-03-25 15:36:101639 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1640 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491641 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1642
[email protected]09356c652014-03-25 15:36:101643 std::vector<MockRead> data2_reads;
1644 std::vector<MockWrite> data2_writes;
1645
1646 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411647 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101648
bncdf80d44fd2016-07-15 20:27:411649 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1650 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101651 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1652 } else {
1653 data2_writes.push_back(
1654 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1655
1656 data2_reads.push_back(
1657 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1658 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1659 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1660 }
rch8e6c6c42015-05-01 14:05:131661 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1662 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491663 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1664
1665 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591666 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491667 // Wait for the preconnect to complete.
1668 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1669 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101670 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491671
1672 // Make the request.
1673 TestCompletionCallback callback;
1674
bnc691fda62016-08-12 00:43:161675 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491676
tfarina42834112016-09-22 13:38:201677 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491679
1680 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011681 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491682
1683 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161684 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101685 TestLoadTimingNotReused(
1686 load_timing_info,
1687 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491688
bnc691fda62016-08-12 00:43:161689 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521690 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491691
wezca1070932016-05-26 20:30:521692 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021693 if (response->was_fetched_via_spdy) {
1694 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1695 } else {
1696 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1697 }
[email protected]a34f61ee2014-03-18 20:59:491698
1699 std::string response_data;
bnc691fda62016-08-12 00:43:161700 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011701 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101702 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491703}
1704
Biljith Jayan45a41722017-08-16 18:43:141705// Test that we do not retry indefinitely when a server sends an error like
1706// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1707// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1708TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1709 HttpRequestInfo request;
1710 request.method = "GET";
1711 request.url = GURL("https://www.foo.com/");
1712
1713 // Check whether we give up after the third try.
1714
1715 // Construct an HTTP2 request and a "Go away" response.
1716 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1717 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1718 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1719 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1720 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1721
1722 // Three go away responses.
1723 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1724 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1725 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1726
1727 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1728 AddSSLSocketData();
1729 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1730 AddSSLSocketData();
1731 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1732 AddSSLSocketData();
1733
1734 TestCompletionCallback callback;
1735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1737
1738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1740
1741 rv = callback.WaitForResult();
1742 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1743}
1744
1745TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1746 HttpRequestInfo request;
1747 request.method = "GET";
1748 request.url = GURL("https://www.foo.com/");
1749
1750 // Check whether we try atleast thrice before giving up.
1751
1752 // Construct an HTTP2 request and a "Go away" response.
1753 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1754 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1755 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1756 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1757 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1758
1759 // Construct a non error HTTP2 response.
1760 SpdySerializedFrame spdy_response_no_error(
1761 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1762 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1763 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1764 CreateMockRead(spdy_data, 2)};
1765
1766 // Two error responses.
1767 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1768 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1769 // Followed by a success response.
1770 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1771
1772 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1773 AddSSLSocketData();
1774 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1775 AddSSLSocketData();
1776 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1777 AddSSLSocketData();
1778
1779 TestCompletionCallback callback;
1780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1782
1783 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1785
1786 rv = callback.WaitForResult();
1787 EXPECT_THAT(rv, IsOk());
1788}
1789
bncd16676a2016-07-20 16:23:011790TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061791 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511792 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1793}
1794
bncd16676a2016-07-20 16:23:011795TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061796 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511797 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251798}
1799
bncd16676a2016-07-20 16:23:011800TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061801 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511802 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251803}
1804
[email protected]d58ceea82014-06-04 10:55:541805// Make sure that on a 408 response (Request Timeout), the request is retried,
1806// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011807TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541808 MockRead read_failure(SYNCHRONOUS,
1809 "HTTP/1.1 408 Request Timeout\r\n"
1810 "Connection: Keep-Alive\r\n"
1811 "Content-Length: 6\r\n\r\n"
1812 "Pickle");
1813 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1814}
1815
bncd16676a2016-07-20 16:23:011816TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491817 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101818 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491819}
1820
bncd16676a2016-07-20 16:23:011821TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491822 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101823 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491824}
1825
bncd16676a2016-07-20 16:23:011826TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491827 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101828 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1829}
1830
bncd16676a2016-07-20 16:23:011831TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101832 MockRead read_failure(ASYNC, OK); // EOF
1833 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1834}
1835
[email protected]d58ceea82014-06-04 10:55:541836// Make sure that on a 408 response (Request Timeout), the request is retried,
1837// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011838TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541839 MockRead read_failure(SYNCHRONOUS,
1840 "HTTP/1.1 408 Request Timeout\r\n"
1841 "Connection: Keep-Alive\r\n"
1842 "Content-Length: 6\r\n\r\n"
1843 "Pickle");
1844 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1845 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1846}
1847
bncd16676a2016-07-20 16:23:011848TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101849 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1850 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1851}
1852
bncd16676a2016-07-20 16:23:011853TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101854 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1855 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1856}
1857
bncd16676a2016-07-20 16:23:011858TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101859 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1860 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1861}
1862
bncd16676a2016-07-20 16:23:011863TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101864 MockRead read_failure(ASYNC, OK); // EOF
1865 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491866}
1867
bncd16676a2016-07-20 16:23:011868TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421869 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251870 request.method = "GET";
bncce36dca22015-04-21 22:11:231871 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251872
danakj1fd259a02016-04-16 03:17:091873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271875
[email protected]3d2a59b2008-09-26 19:44:251876 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061877 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351878 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1879 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061880 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251881 };
[email protected]31a2bfe2010-02-09 08:03:391882 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071883 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251884
[email protected]49639fa2011-12-20 23:22:411885 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251886
tfarina42834112016-09-22 13:38:201887 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251889
1890 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011891 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591892
1893 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161894 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591895 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251896}
1897
1898// What do various browsers do when the server closes a non-keepalive
1899// connection without sending any response header or body?
1900//
1901// IE7: error page
1902// Safari 3.1.2 (Windows): error page
1903// Firefox 3.0.1: blank page
1904// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421905// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1906// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011907TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251908 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061909 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351910 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1911 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061912 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251913 };
[email protected]31a2bfe2010-02-09 08:03:391914 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1915 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011916 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251917}
[email protected]1826a402014-01-08 15:40:481918
[email protected]7a5378b2012-11-04 03:25:171919// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1920// tests. There was a bug causing HttpNetworkTransaction to hang in the
1921// destructor in such situations.
1922// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011923TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171924 HttpRequestInfo request;
1925 request.method = "GET";
bncce36dca22015-04-21 22:11:231926 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171927
danakj1fd259a02016-04-16 03:17:091928 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581929 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191930 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171931
1932 MockRead data_reads[] = {
1933 MockRead("HTTP/1.0 200 OK\r\n"),
1934 MockRead("Connection: keep-alive\r\n"),
1935 MockRead("Content-Length: 100\r\n\r\n"),
1936 MockRead("hello"),
1937 MockRead(SYNCHRONOUS, 0),
1938 };
1939 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071940 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171941
1942 TestCompletionCallback callback;
1943
tfarina42834112016-09-22 13:38:201944 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171946
1947 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011948 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171949
1950 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501951 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171952 if (rv == ERR_IO_PENDING)
1953 rv = callback.WaitForResult();
1954 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501955 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011956 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171957
1958 trans.reset();
fdoray92e35a72016-06-10 15:54:551959 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171960 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1961}
1962
bncd16676a2016-07-20 16:23:011963TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171964 HttpRequestInfo request;
1965 request.method = "GET";
bncce36dca22015-04-21 22:11:231966 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171967
danakj1fd259a02016-04-16 03:17:091968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581969 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191970 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171971
1972 MockRead data_reads[] = {
1973 MockRead("HTTP/1.0 200 OK\r\n"),
1974 MockRead("Connection: keep-alive\r\n"),
1975 MockRead("Content-Length: 100\r\n\r\n"),
1976 MockRead(SYNCHRONOUS, 0),
1977 };
1978 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071979 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171980
1981 TestCompletionCallback callback;
1982
tfarina42834112016-09-22 13:38:201983 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171985
1986 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011987 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171988
1989 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501990 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171991 if (rv == ERR_IO_PENDING)
1992 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011993 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171994
1995 trans.reset();
fdoray92e35a72016-06-10 15:54:551996 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171997 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1998}
1999
[email protected]0b0bf032010-09-21 18:08:502000// Test that we correctly reuse a keep-alive connection after not explicitly
2001// reading the body.
bncd16676a2016-07-20 16:23:012002TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132003 HttpRequestInfo request;
2004 request.method = "GET";
2005 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:132006
vishal.b62985ca92015-04-17 08:45:512007 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072008 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272010
mmenkecc2298e2015-12-07 18:20:182011 const char* request_data =
2012 "GET / HTTP/1.1\r\n"
2013 "Host: www.foo.com\r\n"
2014 "Connection: keep-alive\r\n\r\n";
2015 MockWrite data_writes[] = {
2016 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2017 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2018 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2019 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2020 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2021 };
2022
[email protected]0b0bf032010-09-21 18:08:502023 // Note that because all these reads happen in the same
2024 // StaticSocketDataProvider, it shows that the same socket is being reused for
2025 // all transactions.
mmenkecc2298e2015-12-07 18:20:182026 MockRead data_reads[] = {
2027 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2028 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2029 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2030 MockRead(ASYNC, 7,
2031 "HTTP/1.1 302 Found\r\n"
2032 "Content-Length: 0\r\n\r\n"),
2033 MockRead(ASYNC, 9,
2034 "HTTP/1.1 302 Found\r\n"
2035 "Content-Length: 5\r\n\r\n"
2036 "hello"),
2037 MockRead(ASYNC, 11,
2038 "HTTP/1.1 301 Moved Permanently\r\n"
2039 "Content-Length: 0\r\n\r\n"),
2040 MockRead(ASYNC, 13,
2041 "HTTP/1.1 301 Moved Permanently\r\n"
2042 "Content-Length: 5\r\n\r\n"
2043 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132044
mmenkecc2298e2015-12-07 18:20:182045 // In the next two rounds, IsConnectedAndIdle returns false, due to
2046 // the set_busy_before_sync_reads(true) call, while the
2047 // HttpNetworkTransaction is being shut down, but the socket is still
2048 // reuseable. See http://crbug.com/544255.
2049 MockRead(ASYNC, 15,
2050 "HTTP/1.1 200 Hunky-Dory\r\n"
2051 "Content-Length: 5\r\n\r\n"),
2052 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132053
mmenkecc2298e2015-12-07 18:20:182054 MockRead(ASYNC, 18,
2055 "HTTP/1.1 200 Hunky-Dory\r\n"
2056 "Content-Length: 5\r\n\r\n"
2057 "he"),
2058 MockRead(SYNCHRONOUS, 19, "llo"),
2059
2060 // The body of the final request is actually read.
2061 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2062 MockRead(ASYNC, 22, "hello"),
2063 };
2064 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2065 arraysize(data_writes));
2066 data.set_busy_before_sync_reads(true);
2067 session_deps_.socket_factory->AddSocketDataProvider(&data);
2068
2069 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502070 std::string response_lines[kNumUnreadBodies];
2071
mikecironef22f9812016-10-04 03:40:192072 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182073 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412074 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132075
Jeremy Roman0579ed62017-08-29 15:56:192076 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582077 session.get());
[email protected]fc31d6a42010-06-24 18:05:132078
tfarina42834112016-09-22 13:38:202079 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012080 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132081
[email protected]58e32bb2013-01-21 18:23:252082 LoadTimingInfo load_timing_info;
2083 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2084 if (i == 0) {
2085 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2086 first_socket_log_id = load_timing_info.socket_log_id;
2087 } else {
2088 TestLoadTimingReused(load_timing_info);
2089 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2090 }
2091
[email protected]fc31d6a42010-06-24 18:05:132092 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182093 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132094
mmenkecc2298e2015-12-07 18:20:182095 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502096 response_lines[i] = response->headers->GetStatusLine();
2097
mmenkecc2298e2015-12-07 18:20:182098 // Delete the transaction without reading the response bodies. Then spin
2099 // the message loop, so the response bodies are drained.
2100 trans.reset();
2101 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132102 }
[email protected]0b0bf032010-09-21 18:08:502103
2104 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182105 "HTTP/1.1 204 No Content",
2106 "HTTP/1.1 205 Reset Content",
2107 "HTTP/1.1 304 Not Modified",
2108 "HTTP/1.1 302 Found",
2109 "HTTP/1.1 302 Found",
2110 "HTTP/1.1 301 Moved Permanently",
2111 "HTTP/1.1 301 Moved Permanently",
2112 "HTTP/1.1 200 Hunky-Dory",
2113 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502114 };
2115
mostynb91e0da982015-01-20 19:17:272116 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2117 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502118
2119 for (int i = 0; i < kNumUnreadBodies; ++i)
2120 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2121
[email protected]49639fa2011-12-20 23:22:412122 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202124 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012125 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162126 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182127 ASSERT_TRUE(response);
2128 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2130 std::string response_data;
bnc691fda62016-08-12 00:43:162131 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012132 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502133 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132134}
2135
mmenke5f94fda2016-06-02 20:54:132136// Sockets that receive extra data after a response is complete should not be
2137// reused.
bncd16676a2016-07-20 16:23:012138TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2140 MockWrite data_writes1[] = {
2141 MockWrite("HEAD / HTTP/1.1\r\n"
2142 "Host: www.borked.com\r\n"
2143 "Connection: keep-alive\r\n\r\n"),
2144 };
2145
2146 MockRead data_reads1[] = {
2147 MockRead("HTTP/1.1 200 OK\r\n"
2148 "Connection: keep-alive\r\n"
2149 "Content-Length: 22\r\n\r\n"
2150 "This server is borked."),
2151 };
2152
2153 MockWrite data_writes2[] = {
2154 MockWrite("GET /foo HTTP/1.1\r\n"
2155 "Host: www.borked.com\r\n"
2156 "Connection: keep-alive\r\n\r\n"),
2157 };
2158
2159 MockRead data_reads2[] = {
2160 MockRead("HTTP/1.1 200 OK\r\n"
2161 "Content-Length: 3\r\n\r\n"
2162 "foo"),
2163 };
2164 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2165 data_writes1, arraysize(data_writes1));
2166 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2167 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2168 data_writes2, arraysize(data_writes2));
2169 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2170
2171 TestCompletionCallback callback;
2172 HttpRequestInfo request1;
2173 request1.method = "HEAD";
2174 request1.url = GURL("http://www.borked.com/");
2175
bnc87dcefc2017-05-25 12:47:582176 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192177 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202178 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012179 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132180
2181 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2182 ASSERT_TRUE(response1);
2183 ASSERT_TRUE(response1->headers);
2184 EXPECT_EQ(200, response1->headers->response_code());
2185 EXPECT_TRUE(response1->headers->IsKeepAlive());
2186
2187 std::string response_data1;
robpercival214763f2016-07-01 23:27:012188 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132189 EXPECT_EQ("", response_data1);
2190 // Deleting the transaction attempts to release the socket back into the
2191 // socket pool.
2192 trans1.reset();
2193
2194 HttpRequestInfo request2;
2195 request2.method = "GET";
2196 request2.url = GURL("http://www.borked.com/foo");
2197
bnc87dcefc2017-05-25 12:47:582198 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192199 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202200 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012201 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132202
2203 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2204 ASSERT_TRUE(response2);
2205 ASSERT_TRUE(response2->headers);
2206 EXPECT_EQ(200, response2->headers->response_code());
2207
2208 std::string response_data2;
robpercival214763f2016-07-01 23:27:012209 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132210 EXPECT_EQ("foo", response_data2);
2211}
2212
bncd16676a2016-07-20 16:23:012213TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2215 MockWrite data_writes1[] = {
2216 MockWrite("GET / HTTP/1.1\r\n"
2217 "Host: www.borked.com\r\n"
2218 "Connection: keep-alive\r\n\r\n"),
2219 };
2220
2221 MockRead data_reads1[] = {
2222 MockRead("HTTP/1.1 200 OK\r\n"
2223 "Connection: keep-alive\r\n"
2224 "Content-Length: 22\r\n\r\n"
2225 "This server is borked."
2226 "Bonus data!"),
2227 };
2228
2229 MockWrite data_writes2[] = {
2230 MockWrite("GET /foo HTTP/1.1\r\n"
2231 "Host: www.borked.com\r\n"
2232 "Connection: keep-alive\r\n\r\n"),
2233 };
2234
2235 MockRead data_reads2[] = {
2236 MockRead("HTTP/1.1 200 OK\r\n"
2237 "Content-Length: 3\r\n\r\n"
2238 "foo"),
2239 };
2240 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2241 data_writes1, arraysize(data_writes1));
2242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2243 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2244 data_writes2, arraysize(data_writes2));
2245 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2246
2247 TestCompletionCallback callback;
2248 HttpRequestInfo request1;
2249 request1.method = "GET";
2250 request1.url = GURL("http://www.borked.com/");
2251
bnc87dcefc2017-05-25 12:47:582252 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192253 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202254 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012255 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132256
2257 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2258 ASSERT_TRUE(response1);
2259 ASSERT_TRUE(response1->headers);
2260 EXPECT_EQ(200, response1->headers->response_code());
2261 EXPECT_TRUE(response1->headers->IsKeepAlive());
2262
2263 std::string response_data1;
robpercival214763f2016-07-01 23:27:012264 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132265 EXPECT_EQ("This server is borked.", response_data1);
2266 // Deleting the transaction attempts to release the socket back into the
2267 // socket pool.
2268 trans1.reset();
2269
2270 HttpRequestInfo request2;
2271 request2.method = "GET";
2272 request2.url = GURL("http://www.borked.com/foo");
2273
bnc87dcefc2017-05-25 12:47:582274 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192275 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202276 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012277 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132278
2279 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2280 ASSERT_TRUE(response2);
2281 ASSERT_TRUE(response2->headers);
2282 EXPECT_EQ(200, response2->headers->response_code());
2283
2284 std::string response_data2;
robpercival214763f2016-07-01 23:27:012285 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132286 EXPECT_EQ("foo", response_data2);
2287}
2288
bncd16676a2016-07-20 16:23:012289TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2291 MockWrite data_writes1[] = {
2292 MockWrite("GET / HTTP/1.1\r\n"
2293 "Host: www.borked.com\r\n"
2294 "Connection: keep-alive\r\n\r\n"),
2295 };
2296
2297 MockRead data_reads1[] = {
2298 MockRead("HTTP/1.1 200 OK\r\n"
2299 "Connection: keep-alive\r\n"
2300 "Transfer-Encoding: chunked\r\n\r\n"),
2301 MockRead("16\r\nThis server is borked.\r\n"),
2302 MockRead("0\r\n\r\nBonus data!"),
2303 };
2304
2305 MockWrite data_writes2[] = {
2306 MockWrite("GET /foo HTTP/1.1\r\n"
2307 "Host: www.borked.com\r\n"
2308 "Connection: keep-alive\r\n\r\n"),
2309 };
2310
2311 MockRead data_reads2[] = {
2312 MockRead("HTTP/1.1 200 OK\r\n"
2313 "Content-Length: 3\r\n\r\n"
2314 "foo"),
2315 };
2316 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2317 data_writes1, arraysize(data_writes1));
2318 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2319 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2320 data_writes2, arraysize(data_writes2));
2321 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2322
2323 TestCompletionCallback callback;
2324 HttpRequestInfo request1;
2325 request1.method = "GET";
2326 request1.url = GURL("http://www.borked.com/");
2327
bnc87dcefc2017-05-25 12:47:582328 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202330 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012331 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132332
2333 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2334 ASSERT_TRUE(response1);
2335 ASSERT_TRUE(response1->headers);
2336 EXPECT_EQ(200, response1->headers->response_code());
2337 EXPECT_TRUE(response1->headers->IsKeepAlive());
2338
2339 std::string response_data1;
robpercival214763f2016-07-01 23:27:012340 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132341 EXPECT_EQ("This server is borked.", response_data1);
2342 // Deleting the transaction attempts to release the socket back into the
2343 // socket pool.
2344 trans1.reset();
2345
2346 HttpRequestInfo request2;
2347 request2.method = "GET";
2348 request2.url = GURL("http://www.borked.com/foo");
2349
bnc87dcefc2017-05-25 12:47:582350 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192351 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202352 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012353 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132354
2355 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2356 ASSERT_TRUE(response2);
2357 ASSERT_TRUE(response2->headers);
2358 EXPECT_EQ(200, response2->headers->response_code());
2359
2360 std::string response_data2;
robpercival214763f2016-07-01 23:27:012361 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132362 EXPECT_EQ("foo", response_data2);
2363}
2364
2365// This is a little different from the others - it tests the case that the
2366// HttpStreamParser doesn't know if there's extra data on a socket or not when
2367// the HttpNetworkTransaction is torn down, because the response body hasn't
2368// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012369TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2371 MockWrite data_writes1[] = {
2372 MockWrite("GET / HTTP/1.1\r\n"
2373 "Host: www.borked.com\r\n"
2374 "Connection: keep-alive\r\n\r\n"),
2375 };
2376
2377 MockRead data_reads1[] = {
2378 MockRead("HTTP/1.1 200 OK\r\n"
2379 "Connection: keep-alive\r\n"
2380 "Transfer-Encoding: chunked\r\n\r\n"),
2381 MockRead("16\r\nThis server is borked.\r\n"),
2382 MockRead("0\r\n\r\nBonus data!"),
2383 };
2384 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2385 data_writes1, arraysize(data_writes1));
2386 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2387
2388 TestCompletionCallback callback;
2389 HttpRequestInfo request1;
2390 request1.method = "GET";
2391 request1.url = GURL("http://www.borked.com/");
2392
bnc87dcefc2017-05-25 12:47:582393 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192394 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582395 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012396 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132397
bnc87dcefc2017-05-25 12:47:582398 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132399 ASSERT_TRUE(response1);
2400 ASSERT_TRUE(response1->headers);
2401 EXPECT_EQ(200, response1->headers->response_code());
2402 EXPECT_TRUE(response1->headers->IsKeepAlive());
2403
2404 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2405 // response body.
bnc87dcefc2017-05-25 12:47:582406 trans.reset();
mmenke5f94fda2016-06-02 20:54:132407
2408 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2409 // socket can't be reused, rather than returning it to the socket pool.
2410 base::RunLoop().RunUntilIdle();
2411
2412 // There should be no idle sockets in the pool.
2413 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2414}
2415
[email protected]038e9a32008-10-08 22:40:162416// Test the request-challenge-retry sequence for basic auth.
2417// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012418TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422419 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162420 request.method = "GET";
bncce36dca22015-04-21 22:11:232421 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162422
vishal.b62985ca92015-04-17 08:45:512423 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072424 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272427
[email protected]f9ee6b52008-11-08 06:46:232428 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232429 MockWrite(
2430 "GET / HTTP/1.1\r\n"
2431 "Host: www.example.org\r\n"
2432 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232433 };
2434
[email protected]038e9a32008-10-08 22:40:162435 MockRead data_reads1[] = {
2436 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2437 // Give a couple authenticate options (only the middle one is actually
2438 // supported).
[email protected]22927ad2009-09-21 19:56:192439 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162440 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2441 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2442 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2443 // Large content-length -- won't matter, as connection will be reset.
2444 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062445 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162446 };
2447
2448 // After calling trans->RestartWithAuth(), this is the request we should
2449 // be issuing -- the final header line contains the credentials.
2450 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232451 MockWrite(
2452 "GET / HTTP/1.1\r\n"
2453 "Host: www.example.org\r\n"
2454 "Connection: keep-alive\r\n"
2455 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162456 };
2457
2458 // Lastly, the server responds with the actual content.
2459 MockRead data_reads2[] = {
2460 MockRead("HTTP/1.0 200 OK\r\n"),
2461 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2462 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062463 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162464 };
2465
[email protected]31a2bfe2010-02-09 08:03:392466 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2467 data_writes1, arraysize(data_writes1));
2468 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2469 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2471 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162472
[email protected]49639fa2011-12-20 23:22:412473 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162474
tfarina42834112016-09-22 13:38:202475 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162477
2478 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012479 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162480
[email protected]58e32bb2013-01-21 18:23:252481 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162482 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252483 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2484
sclittlefb249892015-09-10 21:33:222485 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162486 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222487 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162488 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192489
bnc691fda62016-08-12 00:43:162490 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522491 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042492 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162493
[email protected]49639fa2011-12-20 23:22:412494 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162495
bnc691fda62016-08-12 00:43:162496 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162498
2499 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012500 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162501
[email protected]58e32bb2013-01-21 18:23:252502 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162503 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252504 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2505 // The load timing after restart should have a new socket ID, and times after
2506 // those of the first load timing.
2507 EXPECT_LE(load_timing_info1.receive_headers_end,
2508 load_timing_info2.connect_timing.connect_start);
2509 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2510
sclittlefb249892015-09-10 21:33:222511 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162512 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222513 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162514 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192515
bnc691fda62016-08-12 00:43:162516 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522517 ASSERT_TRUE(response);
2518 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162519 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162520}
2521
ttuttled9dbc652015-09-29 20:00:592522// Test the request-challenge-retry sequence for basic auth.
2523// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012524TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592525 HttpRequestInfo request;
2526 request.method = "GET";
2527 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592528
2529 TestNetLog log;
2530 MockHostResolver* resolver = new MockHostResolver();
2531 session_deps_.net_log = &log;
2532 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092533 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592535
2536 resolver->rules()->ClearRules();
2537 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2538
2539 MockWrite data_writes1[] = {
2540 MockWrite("GET / HTTP/1.1\r\n"
2541 "Host: www.example.org\r\n"
2542 "Connection: keep-alive\r\n\r\n"),
2543 };
2544
2545 MockRead data_reads1[] = {
2546 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2547 // Give a couple authenticate options (only the middle one is actually
2548 // supported).
2549 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2550 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2551 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2553 // Large content-length -- won't matter, as connection will be reset.
2554 MockRead("Content-Length: 10000\r\n\r\n"),
2555 MockRead(SYNCHRONOUS, ERR_FAILED),
2556 };
2557
2558 // After calling trans->RestartWithAuth(), this is the request we should
2559 // be issuing -- the final header line contains the credentials.
2560 MockWrite data_writes2[] = {
2561 MockWrite("GET / HTTP/1.1\r\n"
2562 "Host: www.example.org\r\n"
2563 "Connection: keep-alive\r\n"
2564 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2565 };
2566
2567 // Lastly, the server responds with the actual content.
2568 MockRead data_reads2[] = {
2569 MockRead("HTTP/1.0 200 OK\r\n"),
2570 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2571 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2572 };
2573
2574 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2575 data_writes1, arraysize(data_writes1));
2576 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2577 data_writes2, arraysize(data_writes2));
2578 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2579 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2580
2581 TestCompletionCallback callback1;
2582
bnc691fda62016-08-12 00:43:162583 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202584 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592585
2586 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162587 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592588 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2589
2590 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162591 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592592 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162593 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592594
bnc691fda62016-08-12 00:43:162595 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592596 ASSERT_TRUE(response);
2597 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2598
2599 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162600 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592601 ASSERT_FALSE(endpoint.address().empty());
2602 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2603
2604 resolver->rules()->ClearRules();
2605 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2606
2607 TestCompletionCallback callback2;
2608
bnc691fda62016-08-12 00:43:162609 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592610 AuthCredentials(kFoo, kBar), callback2.callback())));
2611
2612 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162613 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592614 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2615 // The load timing after restart should have a new socket ID, and times after
2616 // those of the first load timing.
2617 EXPECT_LE(load_timing_info1.receive_headers_end,
2618 load_timing_info2.connect_timing.connect_start);
2619 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2620
2621 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162622 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592623 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162624 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592625
bnc691fda62016-08-12 00:43:162626 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592627 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522628 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592629 EXPECT_EQ(100, response->headers->GetContentLength());
2630
bnc691fda62016-08-12 00:43:162631 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592632 ASSERT_FALSE(endpoint.address().empty());
2633 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2634}
2635
bncd16676a2016-07-20 16:23:012636TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462637 HttpRequestInfo request;
2638 request.method = "GET";
bncce36dca22015-04-21 22:11:232639 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292640 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462641
danakj1fd259a02016-04-16 03:17:092642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272644
[email protected]861fcd52009-08-26 02:33:462645 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232646 MockWrite(
2647 "GET / HTTP/1.1\r\n"
2648 "Host: www.example.org\r\n"
2649 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462650 };
2651
2652 MockRead data_reads[] = {
2653 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2654 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2655 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2656 // Large content-length -- won't matter, as connection will be reset.
2657 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062658 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462659 };
2660
[email protected]31a2bfe2010-02-09 08:03:392661 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2662 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072663 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412664 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462665
tfarina42834112016-09-22 13:38:202666 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012667 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462668
2669 rv = callback.WaitForResult();
2670 EXPECT_EQ(0, rv);
2671
sclittlefb249892015-09-10 21:33:222672 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162673 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222674 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162675 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192676
bnc691fda62016-08-12 00:43:162677 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522678 ASSERT_TRUE(response);
2679 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462680}
2681
[email protected]2d2697f92009-02-18 21:00:322682// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2683// connection.
bncd16676a2016-07-20 16:23:012684TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182685 // On the second pass, the body read of the auth challenge is synchronous, so
2686 // IsConnectedAndIdle returns false. The socket should still be drained and
2687 // reused. See http://crbug.com/544255.
2688 for (int i = 0; i < 2; ++i) {
2689 HttpRequestInfo request;
2690 request.method = "GET";
2691 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322692
mmenkecc2298e2015-12-07 18:20:182693 TestNetLog log;
2694 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272696
mmenkecc2298e2015-12-07 18:20:182697 MockWrite data_writes[] = {
2698 MockWrite(ASYNC, 0,
2699 "GET / HTTP/1.1\r\n"
2700 "Host: www.example.org\r\n"
2701 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322702
bnc691fda62016-08-12 00:43:162703 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182704 // be issuing -- the final header line contains the credentials.
2705 MockWrite(ASYNC, 6,
2706 "GET / HTTP/1.1\r\n"
2707 "Host: www.example.org\r\n"
2708 "Connection: keep-alive\r\n"
2709 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2710 };
[email protected]2d2697f92009-02-18 21:00:322711
mmenkecc2298e2015-12-07 18:20:182712 MockRead data_reads[] = {
2713 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2714 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2715 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2716 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2717 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322718
mmenkecc2298e2015-12-07 18:20:182719 // Lastly, the server responds with the actual content.
2720 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2721 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2722 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2723 MockRead(ASYNC, 10, "Hello"),
2724 };
[email protected]2d2697f92009-02-18 21:00:322725
mmenkecc2298e2015-12-07 18:20:182726 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2727 arraysize(data_writes));
2728 data.set_busy_before_sync_reads(true);
2729 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462730
mmenkecc2298e2015-12-07 18:20:182731 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322732
bnc691fda62016-08-12 00:43:162733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202734 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012735 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322736
mmenkecc2298e2015-12-07 18:20:182737 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162738 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182739 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322740
bnc691fda62016-08-12 00:43:162741 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182742 ASSERT_TRUE(response);
2743 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322744
mmenkecc2298e2015-12-07 18:20:182745 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252746
bnc691fda62016-08-12 00:43:162747 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2748 callback2.callback());
robpercival214763f2016-07-01 23:27:012749 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322750
mmenkecc2298e2015-12-07 18:20:182751 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162752 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182753 TestLoadTimingReused(load_timing_info2);
2754 // The load timing after restart should have the same socket ID, and times
2755 // those of the first load timing.
2756 EXPECT_LE(load_timing_info1.receive_headers_end,
2757 load_timing_info2.send_start);
2758 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322759
bnc691fda62016-08-12 00:43:162760 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182761 ASSERT_TRUE(response);
2762 EXPECT_FALSE(response->auth_challenge);
2763 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322764
mmenkecc2298e2015-12-07 18:20:182765 std::string response_data;
bnc691fda62016-08-12 00:43:162766 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322767
mmenkecc2298e2015-12-07 18:20:182768 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162769 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182770 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162771 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182772 }
[email protected]2d2697f92009-02-18 21:00:322773}
2774
2775// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2776// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012777TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422778 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322779 request.method = "GET";
bncce36dca22015-04-21 22:11:232780 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322781
danakj1fd259a02016-04-16 03:17:092782 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272783
[email protected]2d2697f92009-02-18 21:00:322784 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162785 MockWrite("GET / HTTP/1.1\r\n"
2786 "Host: www.example.org\r\n"
2787 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322788
bnc691fda62016-08-12 00:43:162789 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232790 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162791 MockWrite("GET / HTTP/1.1\r\n"
2792 "Host: www.example.org\r\n"
2793 "Connection: keep-alive\r\n"
2794 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322795 };
2796
[email protected]2d2697f92009-02-18 21:00:322797 MockRead data_reads1[] = {
2798 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2799 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312800 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322801
2802 // Lastly, the server responds with the actual content.
2803 MockRead("HTTP/1.1 200 OK\r\n"),
2804 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502805 MockRead("Content-Length: 5\r\n\r\n"),
2806 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322807 };
2808
[email protected]2d0a4f92011-05-05 16:38:462809 // An incorrect reconnect would cause this to be read.
2810 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062811 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462812 };
2813
[email protected]31a2bfe2010-02-09 08:03:392814 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2815 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462816 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2817 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072818 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2819 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322820
[email protected]49639fa2011-12-20 23:22:412821 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322822
bnc691fda62016-08-12 00:43:162823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202824 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322826
2827 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012828 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322829
bnc691fda62016-08-12 00:43:162830 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522831 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042832 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322833
[email protected]49639fa2011-12-20 23:22:412834 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322835
bnc691fda62016-08-12 00:43:162836 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322838
2839 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012840 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322841
bnc691fda62016-08-12 00:43:162842 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522843 ASSERT_TRUE(response);
2844 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502845 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322846}
2847
2848// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2849// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012850TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422851 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322852 request.method = "GET";
bncce36dca22015-04-21 22:11:232853 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322854
danakj1fd259a02016-04-16 03:17:092855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272856
[email protected]2d2697f92009-02-18 21:00:322857 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162858 MockWrite("GET / HTTP/1.1\r\n"
2859 "Host: www.example.org\r\n"
2860 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322861
bnc691fda62016-08-12 00:43:162862 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232863 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162864 MockWrite("GET / HTTP/1.1\r\n"
2865 "Host: www.example.org\r\n"
2866 "Connection: keep-alive\r\n"
2867 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322868 };
2869
2870 // Respond with 5 kb of response body.
2871 std::string large_body_string("Unauthorized");
2872 large_body_string.append(5 * 1024, ' ');
2873 large_body_string.append("\r\n");
2874
2875 MockRead data_reads1[] = {
2876 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2877 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2878 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2879 // 5134 = 12 + 5 * 1024 + 2
2880 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062881 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322882
2883 // Lastly, the server responds with the actual content.
2884 MockRead("HTTP/1.1 200 OK\r\n"),
2885 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502886 MockRead("Content-Length: 5\r\n\r\n"),
2887 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322888 };
2889
[email protected]2d0a4f92011-05-05 16:38:462890 // An incorrect reconnect would cause this to be read.
2891 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062892 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462893 };
2894
[email protected]31a2bfe2010-02-09 08:03:392895 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2896 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462897 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2898 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2900 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322901
[email protected]49639fa2011-12-20 23:22:412902 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322903
bnc691fda62016-08-12 00:43:162904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202905 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322907
2908 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012909 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322910
bnc691fda62016-08-12 00:43:162911 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522912 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042913 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322914
[email protected]49639fa2011-12-20 23:22:412915 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322916
bnc691fda62016-08-12 00:43:162917 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322919
2920 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012921 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322922
bnc691fda62016-08-12 00:43:162923 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522924 ASSERT_TRUE(response);
2925 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502926 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322927}
2928
2929// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312930// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012931TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312932 HttpRequestInfo request;
2933 request.method = "GET";
bncce36dca22015-04-21 22:11:232934 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312935
danakj1fd259a02016-04-16 03:17:092936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272937
[email protected]11203f012009-11-12 23:02:312938 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232939 MockWrite(
2940 "GET / HTTP/1.1\r\n"
2941 "Host: www.example.org\r\n"
2942 "Connection: keep-alive\r\n\r\n"),
2943 // This simulates the seemingly successful write to a closed connection
2944 // if the bug is not fixed.
2945 MockWrite(
2946 "GET / HTTP/1.1\r\n"
2947 "Host: www.example.org\r\n"
2948 "Connection: keep-alive\r\n"
2949 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312950 };
2951
2952 MockRead data_reads1[] = {
2953 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2954 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2955 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2956 MockRead("Content-Length: 14\r\n\r\n"),
2957 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062958 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312959 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062960 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312961 };
2962
bnc691fda62016-08-12 00:43:162963 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312964 // be issuing -- the final header line contains the credentials.
2965 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232966 MockWrite(
2967 "GET / HTTP/1.1\r\n"
2968 "Host: www.example.org\r\n"
2969 "Connection: keep-alive\r\n"
2970 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312971 };
2972
2973 // Lastly, the server responds with the actual content.
2974 MockRead data_reads2[] = {
2975 MockRead("HTTP/1.1 200 OK\r\n"),
2976 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502977 MockRead("Content-Length: 5\r\n\r\n"),
2978 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312979 };
2980
[email protected]31a2bfe2010-02-09 08:03:392981 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2982 data_writes1, arraysize(data_writes1));
2983 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2984 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072985 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2986 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312987
[email protected]49639fa2011-12-20 23:22:412988 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312989
bnc691fda62016-08-12 00:43:162990 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202991 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312993
2994 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012995 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312996
bnc691fda62016-08-12 00:43:162997 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522998 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042999 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313000
[email protected]49639fa2011-12-20 23:22:413001 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313002
bnc691fda62016-08-12 00:43:163003 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313005
3006 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013007 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313008
bnc691fda62016-08-12 00:43:163009 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523010 ASSERT_TRUE(response);
3011 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503012 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313013}
3014
[email protected]394816e92010-08-03 07:38:593015// Test the request-challenge-retry sequence for basic auth, over a connection
3016// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013017TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013018 HttpRequestInfo request;
3019 request.method = "GET";
bncce36dca22015-04-21 22:11:233020 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013021 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293022 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013023
3024 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593025 session_deps_.proxy_resolution_service =
3026 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513027 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013028 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093029 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013030
3031 // Since we have proxy, should try to establish tunnel.
3032 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543033 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173034 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543035 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013036 };
3037
mmenkee71e15332015-10-07 16:39:543038 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013039 // connection.
3040 MockRead data_reads1[] = {
3041 // No credentials.
3042 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3043 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543044 };
ttuttle34f63b52015-03-05 04:33:013045
mmenkee71e15332015-10-07 16:39:543046 // Since the first connection couldn't be reused, need to establish another
3047 // once given credentials.
3048 MockWrite data_writes2[] = {
3049 // After calling trans->RestartWithAuth(), this is the request we should
3050 // be issuing -- the final header line contains the credentials.
3051 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173052 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543053 "Proxy-Connection: keep-alive\r\n"
3054 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3055
3056 MockWrite("GET / HTTP/1.1\r\n"
3057 "Host: www.example.org\r\n"
3058 "Connection: keep-alive\r\n\r\n"),
3059 };
3060
3061 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013062 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3063
3064 MockRead("HTTP/1.1 200 OK\r\n"),
3065 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3066 MockRead("Content-Length: 5\r\n\r\n"),
3067 MockRead(SYNCHRONOUS, "hello"),
3068 };
3069
3070 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3071 data_writes1, arraysize(data_writes1));
3072 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543073 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3074 data_writes2, arraysize(data_writes2));
3075 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013076 SSLSocketDataProvider ssl(ASYNC, OK);
3077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3078
3079 TestCompletionCallback callback1;
3080
bnc87dcefc2017-05-25 12:47:583081 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193082 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013083
3084 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013086
3087 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013088 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463089 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013090 log.GetEntries(&entries);
3091 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003092 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3093 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013094 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003095 entries, pos,
3096 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3097 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013098
3099 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523100 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013101 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523102 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013103 EXPECT_EQ(407, response->headers->response_code());
3104 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3105 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3106
3107 LoadTimingInfo load_timing_info;
3108 // CONNECT requests and responses are handled at the connect job level, so
3109 // the transaction does not yet have a connection.
3110 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3111
3112 TestCompletionCallback callback2;
3113
3114 rv =
3115 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013117
3118 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013119 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013120
3121 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523122 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013123
3124 EXPECT_TRUE(response->headers->IsKeepAlive());
3125 EXPECT_EQ(200, response->headers->response_code());
3126 EXPECT_EQ(5, response->headers->GetContentLength());
3127 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3128
3129 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523130 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013131
3132 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3133 TestLoadTimingNotReusedWithPac(load_timing_info,
3134 CONNECT_TIMING_HAS_SSL_TIMES);
3135
3136 trans.reset();
3137 session->CloseAllConnections();
3138}
3139
3140// Test the request-challenge-retry sequence for basic auth, over a connection
3141// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013142TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593143 HttpRequestInfo request;
3144 request.method = "GET";
bncce36dca22015-04-21 22:11:233145 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593146 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293147 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593148
[email protected]cb9bf6ca2011-01-28 13:15:273149 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593150 session_deps_.proxy_resolution_service =
3151 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513152 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073153 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273155
[email protected]394816e92010-08-03 07:38:593156 // Since we have proxy, should try to establish tunnel.
3157 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543158 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173159 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543160 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113161 };
3162
mmenkee71e15332015-10-07 16:39:543163 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083164 // connection.
3165 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543166 // No credentials.
3167 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3168 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3169 MockRead("Proxy-Connection: close\r\n\r\n"),
3170 };
mmenkee0b5c882015-08-26 20:29:113171
mmenkee71e15332015-10-07 16:39:543172 MockWrite data_writes2[] = {
3173 // After calling trans->RestartWithAuth(), this is the request we should
3174 // be issuing -- the final header line contains the credentials.
3175 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173176 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543177 "Proxy-Connection: keep-alive\r\n"
3178 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083179
mmenkee71e15332015-10-07 16:39:543180 MockWrite("GET / HTTP/1.1\r\n"
3181 "Host: www.example.org\r\n"
3182 "Connection: keep-alive\r\n\r\n"),
3183 };
3184
3185 MockRead data_reads2[] = {
3186 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3187
3188 MockRead("HTTP/1.1 200 OK\r\n"),
3189 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3190 MockRead("Content-Length: 5\r\n\r\n"),
3191 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593192 };
3193
3194 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3195 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073196 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543197 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3198 data_writes2, arraysize(data_writes2));
3199 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063200 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593202
[email protected]49639fa2011-12-20 23:22:413203 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593204
bnc87dcefc2017-05-25 12:47:583205 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193206 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503207
[email protected]49639fa2011-12-20 23:22:413208 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593210
3211 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013212 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463213 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403214 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593215 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003216 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3217 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593218 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403219 entries, pos,
mikecirone8b85c432016-09-08 19:11:003220 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3221 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593222
3223 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523224 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013225 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523226 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593227 EXPECT_EQ(407, response->headers->response_code());
3228 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043229 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593230
[email protected]029c83b62013-01-24 05:28:203231 LoadTimingInfo load_timing_info;
3232 // CONNECT requests and responses are handled at the connect job level, so
3233 // the transaction does not yet have a connection.
3234 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3235
[email protected]49639fa2011-12-20 23:22:413236 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593237
[email protected]49639fa2011-12-20 23:22:413238 rv = trans->RestartWithAuth(
3239 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593241
3242 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013243 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593244
3245 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523246 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593247
3248 EXPECT_TRUE(response->headers->IsKeepAlive());
3249 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503250 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593251 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3252
3253 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523254 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503255
[email protected]029c83b62013-01-24 05:28:203256 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3257 TestLoadTimingNotReusedWithPac(load_timing_info,
3258 CONNECT_TIMING_HAS_SSL_TIMES);
3259
[email protected]0b0bf032010-09-21 18:08:503260 trans.reset();
[email protected]102e27c2011-02-23 01:01:313261 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593262}
3263
[email protected]11203f012009-11-12 23:02:313264// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013265// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013266TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233267 // On the second pass, the body read of the auth challenge is synchronous, so
3268 // IsConnectedAndIdle returns false. The socket should still be drained and
3269 // reused. See http://crbug.com/544255.
3270 for (int i = 0; i < 2; ++i) {
3271 HttpRequestInfo request;
3272 request.method = "GET";
3273 request.url = GURL("https://www.example.org/");
3274 // Ensure that proxy authentication is attempted even
3275 // when the no authentication data flag is set.
3276 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013277
mmenked39192ee2015-12-09 00:57:233278 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593279 session_deps_.proxy_resolution_service =
3280 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233281 BoundTestNetLog log;
3282 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093283 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013284
bnc691fda62016-08-12 00:43:163285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013286
mmenked39192ee2015-12-09 00:57:233287 // Since we have proxy, should try to establish tunnel.
3288 MockWrite data_writes1[] = {
3289 MockWrite(ASYNC, 0,
3290 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3291 "Host: www.example.org:443\r\n"
3292 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013293
bnc691fda62016-08-12 00:43:163294 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233295 // be issuing -- the final header line contains the credentials.
3296 MockWrite(ASYNC, 3,
3297 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3298 "Host: www.example.org:443\r\n"
3299 "Proxy-Connection: keep-alive\r\n"
3300 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3301 };
ttuttle34f63b52015-03-05 04:33:013302
mmenked39192ee2015-12-09 00:57:233303 // The proxy responds to the connect with a 407, using a persistent
3304 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3305 MockRead data_reads1[] = {
3306 // No credentials.
3307 MockRead(ASYNC, 1,
3308 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3309 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3310 "Proxy-Connection: keep-alive\r\n"
3311 "Content-Length: 10\r\n\r\n"),
3312 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013313
mmenked39192ee2015-12-09 00:57:233314 // Wrong credentials (wrong password).
3315 MockRead(ASYNC, 4,
3316 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3317 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3318 "Proxy-Connection: keep-alive\r\n"
3319 "Content-Length: 10\r\n\r\n"),
3320 // No response body because the test stops reading here.
3321 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3322 };
ttuttle34f63b52015-03-05 04:33:013323
mmenked39192ee2015-12-09 00:57:233324 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3325 arraysize(data_writes1));
3326 data1.set_busy_before_sync_reads(true);
3327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013328
mmenked39192ee2015-12-09 00:57:233329 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013330
bnc691fda62016-08-12 00:43:163331 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013332 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013333
mmenked39192ee2015-12-09 00:57:233334 TestNetLogEntry::List entries;
3335 log.GetEntries(&entries);
3336 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003337 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3338 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233339 ExpectLogContainsSomewhere(
3340 entries, pos,
mikecirone8b85c432016-09-08 19:11:003341 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3342 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013343
bnc691fda62016-08-12 00:43:163344 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233345 ASSERT_TRUE(response);
3346 ASSERT_TRUE(response->headers);
3347 EXPECT_TRUE(response->headers->IsKeepAlive());
3348 EXPECT_EQ(407, response->headers->response_code());
3349 EXPECT_EQ(10, response->headers->GetContentLength());
3350 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3351 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013352
mmenked39192ee2015-12-09 00:57:233353 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013354
mmenked39192ee2015-12-09 00:57:233355 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163356 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3357 callback2.callback());
robpercival214763f2016-07-01 23:27:013358 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013359
bnc691fda62016-08-12 00:43:163360 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233361 ASSERT_TRUE(response);
3362 ASSERT_TRUE(response->headers);
3363 EXPECT_TRUE(response->headers->IsKeepAlive());
3364 EXPECT_EQ(407, response->headers->response_code());
3365 EXPECT_EQ(10, response->headers->GetContentLength());
3366 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3367 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013368
mmenked39192ee2015-12-09 00:57:233369 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3370 // out of scope.
3371 session->CloseAllConnections();
3372 }
ttuttle34f63b52015-03-05 04:33:013373}
3374
3375// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3376// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013377TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233378 // On the second pass, the body read of the auth challenge is synchronous, so
3379 // IsConnectedAndIdle returns false. The socket should still be drained and
3380 // reused. See http://crbug.com/544255.
3381 for (int i = 0; i < 2; ++i) {
3382 HttpRequestInfo request;
3383 request.method = "GET";
3384 request.url = GURL("https://www.example.org/");
3385 // Ensure that proxy authentication is attempted even
3386 // when the no authentication data flag is set.
3387 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3388
3389 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593390 session_deps_.proxy_resolution_service =
3391 ProxyResolutionService::CreateFixed("myproxy:70");
mmenked39192ee2015-12-09 00:57:233392 BoundTestNetLog log;
3393 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233395
bnc691fda62016-08-12 00:43:163396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233397
3398 // Since we have proxy, should try to establish tunnel.
3399 MockWrite data_writes1[] = {
3400 MockWrite(ASYNC, 0,
3401 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3402 "Host: www.example.org:443\r\n"
3403 "Proxy-Connection: keep-alive\r\n\r\n"),
3404
bnc691fda62016-08-12 00:43:163405 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233406 // be issuing -- the final header line contains the credentials.
3407 MockWrite(ASYNC, 3,
3408 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3409 "Host: www.example.org:443\r\n"
3410 "Proxy-Connection: keep-alive\r\n"
3411 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3412 };
3413
3414 // The proxy responds to the connect with a 407, using a persistent
3415 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3416 MockRead data_reads1[] = {
3417 // No credentials.
3418 MockRead(ASYNC, 1,
3419 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3420 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3421 "Content-Length: 10\r\n\r\n"),
3422 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3423
3424 // Wrong credentials (wrong password).
3425 MockRead(ASYNC, 4,
3426 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3427 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3428 "Content-Length: 10\r\n\r\n"),
3429 // No response body because the test stops reading here.
3430 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3431 };
3432
3433 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3434 arraysize(data_writes1));
3435 data1.set_busy_before_sync_reads(true);
3436 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3437
3438 TestCompletionCallback callback1;
3439
bnc691fda62016-08-12 00:43:163440 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013441 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233442
3443 TestNetLogEntry::List entries;
3444 log.GetEntries(&entries);
3445 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003446 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3447 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233448 ExpectLogContainsSomewhere(
3449 entries, pos,
mikecirone8b85c432016-09-08 19:11:003450 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3451 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233452
bnc691fda62016-08-12 00:43:163453 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233454 ASSERT_TRUE(response);
3455 ASSERT_TRUE(response->headers);
3456 EXPECT_TRUE(response->headers->IsKeepAlive());
3457 EXPECT_EQ(407, response->headers->response_code());
3458 EXPECT_EQ(10, response->headers->GetContentLength());
3459 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3460 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3461
3462 TestCompletionCallback callback2;
3463
3464 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163465 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3466 callback2.callback());
robpercival214763f2016-07-01 23:27:013467 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233468
bnc691fda62016-08-12 00:43:163469 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233470 ASSERT_TRUE(response);
3471 ASSERT_TRUE(response->headers);
3472 EXPECT_TRUE(response->headers->IsKeepAlive());
3473 EXPECT_EQ(407, response->headers->response_code());
3474 EXPECT_EQ(10, response->headers->GetContentLength());
3475 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3476 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3477
3478 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3479 // out of scope.
3480 session->CloseAllConnections();
3481 }
3482}
3483
3484// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3485// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3486// the case the server sends extra data on the original socket, so it can't be
3487// reused.
bncd16676a2016-07-20 16:23:013488TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273489 HttpRequestInfo request;
3490 request.method = "GET";
bncce36dca22015-04-21 22:11:233491 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273492 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293493 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273494
[email protected]2d2697f92009-02-18 21:00:323495 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593496 session_deps_.proxy_resolution_service =
3497 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513498 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073499 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323501
[email protected]2d2697f92009-02-18 21:00:323502 // Since we have proxy, should try to establish tunnel.
3503 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233504 MockWrite(ASYNC, 0,
3505 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173506 "Host: www.example.org:443\r\n"
3507 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233508 };
[email protected]2d2697f92009-02-18 21:00:323509
mmenked39192ee2015-12-09 00:57:233510 // The proxy responds to the connect with a 407, using a persistent, but sends
3511 // extra data, so the socket cannot be reused.
3512 MockRead data_reads1[] = {
3513 // No credentials.
3514 MockRead(ASYNC, 1,
3515 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3516 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3517 "Content-Length: 10\r\n\r\n"),
3518 MockRead(SYNCHRONOUS, 2, "0123456789"),
3519 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3520 };
3521
3522 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233523 // After calling trans->RestartWithAuth(), this is the request we should
3524 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233525 MockWrite(ASYNC, 0,
3526 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173527 "Host: www.example.org:443\r\n"
3528 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233529 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3530
3531 MockWrite(ASYNC, 2,
3532 "GET / HTTP/1.1\r\n"
3533 "Host: www.example.org\r\n"
3534 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323535 };
3536
mmenked39192ee2015-12-09 00:57:233537 MockRead data_reads2[] = {
3538 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323539
mmenked39192ee2015-12-09 00:57:233540 MockRead(ASYNC, 3,
3541 "HTTP/1.1 200 OK\r\n"
3542 "Content-Type: text/html; charset=iso-8859-1\r\n"
3543 "Content-Length: 5\r\n\r\n"),
3544 // No response body because the test stops reading here.
3545 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323546 };
3547
mmenked39192ee2015-12-09 00:57:233548 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3549 arraysize(data_writes1));
3550 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073551 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233552 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3553 arraysize(data_writes2));
3554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3555 SSLSocketDataProvider ssl(ASYNC, OK);
3556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323557
[email protected]49639fa2011-12-20 23:22:413558 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323559
bnc87dcefc2017-05-25 12:47:583560 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193561 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323562
mmenked39192ee2015-12-09 00:57:233563 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013564 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233565
mmenke43758e62015-05-04 21:09:463566 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403567 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393568 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003569 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3570 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393571 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403572 entries, pos,
mikecirone8b85c432016-09-08 19:11:003573 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3574 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323575
[email protected]1c773ea12009-04-28 19:58:423576 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243577 ASSERT_TRUE(response);
3578 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323579 EXPECT_TRUE(response->headers->IsKeepAlive());
3580 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423581 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043582 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323583
mmenked39192ee2015-12-09 00:57:233584 LoadTimingInfo load_timing_info;
3585 // CONNECT requests and responses are handled at the connect job level, so
3586 // the transaction does not yet have a connection.
3587 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3588
[email protected]49639fa2011-12-20 23:22:413589 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323590
mmenked39192ee2015-12-09 00:57:233591 rv =
3592 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013593 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323594
[email protected]2d2697f92009-02-18 21:00:323595 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233596 EXPECT_EQ(200, response->headers->response_code());
3597 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423598 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133599
mmenked39192ee2015-12-09 00:57:233600 // The password prompt info should not be set.
3601 EXPECT_FALSE(response->auth_challenge);
3602
3603 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3604 TestLoadTimingNotReusedWithPac(load_timing_info,
3605 CONNECT_TIMING_HAS_SSL_TIMES);
3606
3607 trans.reset();
[email protected]102e27c2011-02-23 01:01:313608 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323609}
3610
mmenkee71e15332015-10-07 16:39:543611// Test the case a proxy closes a socket while the challenge body is being
3612// drained.
bncd16676a2016-07-20 16:23:013613TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543614 HttpRequestInfo request;
3615 request.method = "GET";
3616 request.url = GURL("https://www.example.org/");
3617 // Ensure that proxy authentication is attempted even
3618 // when the no authentication data flag is set.
3619 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3620
3621 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593622 session_deps_.proxy_resolution_service =
3623 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093624 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543625
bnc691fda62016-08-12 00:43:163626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543627
3628 // Since we have proxy, should try to establish tunnel.
3629 MockWrite data_writes1[] = {
3630 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173631 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543632 "Proxy-Connection: keep-alive\r\n\r\n"),
3633 };
3634
3635 // The proxy responds to the connect with a 407, using a persistent
3636 // connection.
3637 MockRead data_reads1[] = {
3638 // No credentials.
3639 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3640 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3641 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3642 // Server hands up in the middle of the body.
3643 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3644 };
3645
3646 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163647 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543648 // be issuing -- the final header line contains the credentials.
3649 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173650 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543651 "Proxy-Connection: keep-alive\r\n"
3652 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3653
3654 MockWrite("GET / HTTP/1.1\r\n"
3655 "Host: www.example.org\r\n"
3656 "Connection: keep-alive\r\n\r\n"),
3657 };
3658
3659 MockRead data_reads2[] = {
3660 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3661
3662 MockRead("HTTP/1.1 200 OK\r\n"),
3663 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3664 MockRead("Content-Length: 5\r\n\r\n"),
3665 MockRead(SYNCHRONOUS, "hello"),
3666 };
3667
3668 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3669 data_writes1, arraysize(data_writes1));
3670 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3671 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3672 data_writes2, arraysize(data_writes2));
3673 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3674 SSLSocketDataProvider ssl(ASYNC, OK);
3675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3676
3677 TestCompletionCallback callback;
3678
tfarina42834112016-09-22 13:38:203679 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013680 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543681
bnc691fda62016-08-12 00:43:163682 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543683 ASSERT_TRUE(response);
3684 ASSERT_TRUE(response->headers);
3685 EXPECT_TRUE(response->headers->IsKeepAlive());
3686 EXPECT_EQ(407, response->headers->response_code());
3687 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3688
bnc691fda62016-08-12 00:43:163689 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013690 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543691
bnc691fda62016-08-12 00:43:163692 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543693 ASSERT_TRUE(response);
3694 ASSERT_TRUE(response->headers);
3695 EXPECT_TRUE(response->headers->IsKeepAlive());
3696 EXPECT_EQ(200, response->headers->response_code());
3697 std::string body;
bnc691fda62016-08-12 00:43:163698 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543699 EXPECT_EQ("hello", body);
3700}
3701
[email protected]a8e9b162009-03-12 00:06:443702// Test that we don't read the response body when we fail to establish a tunnel,
3703// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013704TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273705 HttpRequestInfo request;
3706 request.method = "GET";
bncce36dca22015-04-21 22:11:233707 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273708
[email protected]a8e9b162009-03-12 00:06:443709 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593710 session_deps_.proxy_resolution_service =
3711 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443712
danakj1fd259a02016-04-16 03:17:093713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443714
bnc691fda62016-08-12 00:43:163715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443716
[email protected]a8e9b162009-03-12 00:06:443717 // Since we have proxy, should try to establish tunnel.
3718 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173719 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3720 "Host: www.example.org:443\r\n"
3721 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443722 };
3723
3724 // The proxy responds to the connect with a 407.
3725 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243726 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3727 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3728 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233729 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243730 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443731 };
3732
[email protected]31a2bfe2010-02-09 08:03:393733 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3734 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073735 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443736
[email protected]49639fa2011-12-20 23:22:413737 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443738
tfarina42834112016-09-22 13:38:203739 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443741
3742 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013743 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443744
bnc691fda62016-08-12 00:43:163745 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243746 ASSERT_TRUE(response);
3747 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443748 EXPECT_TRUE(response->headers->IsKeepAlive());
3749 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423750 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443751
3752 std::string response_data;
bnc691fda62016-08-12 00:43:163753 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013754 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183755
3756 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313757 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443758}
3759
ttuttle7933c112015-01-06 00:55:243760// Test that we don't pass extraneous headers from the proxy's response to the
3761// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013762TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243763 HttpRequestInfo request;
3764 request.method = "GET";
bncce36dca22015-04-21 22:11:233765 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243766
3767 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593768 session_deps_.proxy_resolution_service =
3769 ProxyResolutionService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243770
danakj1fd259a02016-04-16 03:17:093771 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243772
bnc691fda62016-08-12 00:43:163773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243774
3775 // Since we have proxy, should try to establish tunnel.
3776 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173777 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3778 "Host: www.example.org:443\r\n"
3779 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243780 };
3781
3782 // The proxy responds to the connect with a 407.
3783 MockRead data_reads[] = {
3784 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3785 MockRead("X-Foo: bar\r\n"),
3786 MockRead("Set-Cookie: foo=bar\r\n"),
3787 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3788 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233789 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243790 };
3791
3792 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3793 arraysize(data_writes));
3794 session_deps_.socket_factory->AddSocketDataProvider(&data);
3795
3796 TestCompletionCallback callback;
3797
tfarina42834112016-09-22 13:38:203798 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243800
3801 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013802 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243803
bnc691fda62016-08-12 00:43:163804 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243805 ASSERT_TRUE(response);
3806 ASSERT_TRUE(response->headers);
3807 EXPECT_TRUE(response->headers->IsKeepAlive());
3808 EXPECT_EQ(407, response->headers->response_code());
3809 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3810 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3811 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3812
3813 std::string response_data;
bnc691fda62016-08-12 00:43:163814 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013815 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243816
3817 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3818 session->CloseAllConnections();
3819}
3820
[email protected]8fdbcd22010-05-05 02:54:523821// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3822// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013823TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523824 HttpRequestInfo request;
3825 request.method = "GET";
bncce36dca22015-04-21 22:11:233826 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523827
[email protected]cb9bf6ca2011-01-28 13:15:273828 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273831
[email protected]8fdbcd22010-05-05 02:54:523832 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233833 MockWrite(
3834 "GET / HTTP/1.1\r\n"
3835 "Host: www.example.org\r\n"
3836 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523837 };
3838
3839 MockRead data_reads1[] = {
3840 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3841 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3842 // Large content-length -- won't matter, as connection will be reset.
3843 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063844 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523845 };
3846
3847 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3848 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073849 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523850
[email protected]49639fa2011-12-20 23:22:413851 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523852
tfarina42834112016-09-22 13:38:203853 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013854 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523855
3856 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013857 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523858}
3859
[email protected]7a67a8152010-11-05 18:31:103860// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3861// through a non-authenticating proxy. The request should fail with
3862// ERR_UNEXPECTED_PROXY_AUTH.
3863// Note that it is impossible to detect if an HTTP server returns a 407 through
3864// a non-authenticating proxy - there is nothing to indicate whether the
3865// response came from the proxy or the server, so it is treated as if the proxy
3866// issued the challenge.
bncd16676a2016-07-20 16:23:013867TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273868 HttpRequestInfo request;
3869 request.method = "GET";
bncce36dca22015-04-21 22:11:233870 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273871
Lily Houghton8c2f97d2018-01-22 05:06:593872 session_deps_.proxy_resolution_service =
3873 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513874 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073875 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103877
[email protected]7a67a8152010-11-05 18:31:103878 // Since we have proxy, should try to establish tunnel.
3879 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173880 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3881 "Host: www.example.org:443\r\n"
3882 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103883
rsleevidb16bb02015-11-12 23:47:173884 MockWrite("GET / HTTP/1.1\r\n"
3885 "Host: www.example.org\r\n"
3886 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103887 };
3888
3889 MockRead data_reads1[] = {
3890 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3891
3892 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3893 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3894 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063895 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103896 };
3897
3898 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3899 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073900 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063901 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073902 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103903
[email protected]49639fa2011-12-20 23:22:413904 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103905
bnc691fda62016-08-12 00:43:163906 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103907
bnc691fda62016-08-12 00:43:163908 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103910
3911 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013912 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463913 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403914 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103915 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003916 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3917 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103918 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403919 entries, pos,
mikecirone8b85c432016-09-08 19:11:003920 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3921 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103922}
[email protected]2df19bb2010-08-25 20:13:463923
mmenke2a1781d2015-10-07 19:25:333924// Test a proxy auth scheme that allows default credentials and a proxy server
3925// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013926TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333927 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3928 HttpRequestInfo request;
3929 request.method = "GET";
3930 request.url = GURL("https://www.example.org/");
3931
3932 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593933 session_deps_.proxy_resolution_service =
3934 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:333935
Jeremy Roman0579ed62017-08-29 15:56:193936 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333937 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193938 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333939 mock_handler->set_allows_default_credentials(true);
3940 auth_handler_factory->AddMockHandler(mock_handler.release(),
3941 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483942 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333943
3944 // Add NetLog just so can verify load timing information gets a NetLog ID.
3945 NetLog net_log;
3946 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093947 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333948
3949 // Since we have proxy, should try to establish tunnel.
3950 MockWrite data_writes1[] = {
3951 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173952 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333953 "Proxy-Connection: keep-alive\r\n\r\n"),
3954 };
3955
3956 // The proxy responds to the connect with a 407, using a non-persistent
3957 // connection.
3958 MockRead data_reads1[] = {
3959 // No credentials.
3960 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3961 MockRead("Proxy-Authenticate: Mock\r\n"),
3962 MockRead("Proxy-Connection: close\r\n\r\n"),
3963 };
3964
3965 // Since the first connection couldn't be reused, need to establish another
3966 // once given credentials.
3967 MockWrite data_writes2[] = {
3968 // After calling trans->RestartWithAuth(), this is the request we should
3969 // be issuing -- the final header line contains the credentials.
3970 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173971 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333972 "Proxy-Connection: keep-alive\r\n"
3973 "Proxy-Authorization: auth_token\r\n\r\n"),
3974
3975 MockWrite("GET / HTTP/1.1\r\n"
3976 "Host: www.example.org\r\n"
3977 "Connection: keep-alive\r\n\r\n"),
3978 };
3979
3980 MockRead data_reads2[] = {
3981 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3982
3983 MockRead("HTTP/1.1 200 OK\r\n"),
3984 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3985 MockRead("Content-Length: 5\r\n\r\n"),
3986 MockRead(SYNCHRONOUS, "hello"),
3987 };
3988
3989 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3990 data_writes1, arraysize(data_writes1));
3991 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3992 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3993 data_writes2, arraysize(data_writes2));
3994 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3995 SSLSocketDataProvider ssl(ASYNC, OK);
3996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3997
bnc87dcefc2017-05-25 12:47:583998 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193999 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334000
4001 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204002 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014003 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334004
4005 const HttpResponseInfo* response = trans->GetResponseInfo();
4006 ASSERT_TRUE(response);
4007 ASSERT_TRUE(response->headers);
4008 EXPECT_FALSE(response->headers->IsKeepAlive());
4009 EXPECT_EQ(407, response->headers->response_code());
4010 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4011 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524012 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334013
4014 LoadTimingInfo load_timing_info;
4015 // CONNECT requests and responses are handled at the connect job level, so
4016 // the transaction does not yet have a connection.
4017 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4018
4019 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014020 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334021 response = trans->GetResponseInfo();
4022 ASSERT_TRUE(response);
4023 ASSERT_TRUE(response->headers);
4024 EXPECT_TRUE(response->headers->IsKeepAlive());
4025 EXPECT_EQ(200, response->headers->response_code());
4026 EXPECT_EQ(5, response->headers->GetContentLength());
4027 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4028
4029 // The password prompt info should not be set.
4030 EXPECT_FALSE(response->auth_challenge);
4031
4032 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4033 TestLoadTimingNotReusedWithPac(load_timing_info,
4034 CONNECT_TIMING_HAS_SSL_TIMES);
4035
4036 trans.reset();
4037 session->CloseAllConnections();
4038}
4039
4040// Test a proxy auth scheme that allows default credentials and a proxy server
4041// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014042TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334043 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4044 HttpRequestInfo request;
4045 request.method = "GET";
4046 request.url = GURL("https://www.example.org/");
4047
4048 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594049 session_deps_.proxy_resolution_service =
4050 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334051
Jeremy Roman0579ed62017-08-29 15:56:194052 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334053 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194054 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334055 mock_handler->set_allows_default_credentials(true);
4056 auth_handler_factory->AddMockHandler(mock_handler.release(),
4057 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484058 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334059
4060 // Add NetLog just so can verify load timing information gets a NetLog ID.
4061 NetLog net_log;
4062 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094063 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334064
4065 // Should try to establish tunnel.
4066 MockWrite data_writes1[] = {
4067 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174068 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334069 "Proxy-Connection: keep-alive\r\n\r\n"),
4070
4071 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174072 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334073 "Proxy-Connection: keep-alive\r\n"
4074 "Proxy-Authorization: auth_token\r\n\r\n"),
4075 };
4076
4077 // The proxy responds to the connect with a 407, using a non-persistent
4078 // connection.
4079 MockRead data_reads1[] = {
4080 // No credentials.
4081 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4082 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4083 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4084 };
4085
4086 // Since the first connection was closed, need to establish another once given
4087 // credentials.
4088 MockWrite data_writes2[] = {
4089 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174090 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334091 "Proxy-Connection: keep-alive\r\n"
4092 "Proxy-Authorization: auth_token\r\n\r\n"),
4093
4094 MockWrite("GET / HTTP/1.1\r\n"
4095 "Host: www.example.org\r\n"
4096 "Connection: keep-alive\r\n\r\n"),
4097 };
4098
4099 MockRead data_reads2[] = {
4100 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4101
4102 MockRead("HTTP/1.1 200 OK\r\n"),
4103 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4104 MockRead("Content-Length: 5\r\n\r\n"),
4105 MockRead(SYNCHRONOUS, "hello"),
4106 };
4107
4108 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4109 data_writes1, arraysize(data_writes1));
4110 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4111 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4112 data_writes2, arraysize(data_writes2));
4113 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4114 SSLSocketDataProvider ssl(ASYNC, OK);
4115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4116
bnc87dcefc2017-05-25 12:47:584117 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194118 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334119
4120 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204121 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014122 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334123
4124 const HttpResponseInfo* response = trans->GetResponseInfo();
4125 ASSERT_TRUE(response);
4126 ASSERT_TRUE(response->headers);
4127 EXPECT_TRUE(response->headers->IsKeepAlive());
4128 EXPECT_EQ(407, response->headers->response_code());
4129 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4130 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4131 EXPECT_FALSE(response->auth_challenge);
4132
4133 LoadTimingInfo load_timing_info;
4134 // CONNECT requests and responses are handled at the connect job level, so
4135 // the transaction does not yet have a connection.
4136 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4137
4138 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014139 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334140
4141 response = trans->GetResponseInfo();
4142 ASSERT_TRUE(response);
4143 ASSERT_TRUE(response->headers);
4144 EXPECT_TRUE(response->headers->IsKeepAlive());
4145 EXPECT_EQ(200, response->headers->response_code());
4146 EXPECT_EQ(5, response->headers->GetContentLength());
4147 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4148
4149 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524150 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334151
4152 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4153 TestLoadTimingNotReusedWithPac(load_timing_info,
4154 CONNECT_TIMING_HAS_SSL_TIMES);
4155
4156 trans.reset();
4157 session->CloseAllConnections();
4158}
4159
4160// Test a proxy auth scheme that allows default credentials and a proxy server
4161// that hangs up when credentials are initially sent, and hangs up again when
4162// they are retried.
bncd16676a2016-07-20 16:23:014163TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334164 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4165 HttpRequestInfo request;
4166 request.method = "GET";
4167 request.url = GURL("https://www.example.org/");
4168
4169 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594170 session_deps_.proxy_resolution_service =
4171 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334172
Jeremy Roman0579ed62017-08-29 15:56:194173 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334174 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194175 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334176 mock_handler->set_allows_default_credentials(true);
4177 auth_handler_factory->AddMockHandler(mock_handler.release(),
4178 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484179 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334180
4181 // Add NetLog just so can verify load timing information gets a NetLog ID.
4182 NetLog net_log;
4183 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094184 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334185
4186 // Should try to establish tunnel.
4187 MockWrite data_writes1[] = {
4188 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174189 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334190 "Proxy-Connection: keep-alive\r\n\r\n"),
4191
4192 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174193 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334194 "Proxy-Connection: keep-alive\r\n"
4195 "Proxy-Authorization: auth_token\r\n\r\n"),
4196 };
4197
4198 // The proxy responds to the connect with a 407, and then hangs up after the
4199 // second request is sent.
4200 MockRead data_reads1[] = {
4201 // No credentials.
4202 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4203 MockRead("Content-Length: 0\r\n"),
4204 MockRead("Proxy-Connection: keep-alive\r\n"),
4205 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4206 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4207 };
4208
4209 // HttpNetworkTransaction sees a reused connection that was closed with
4210 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4211 // request.
4212 MockWrite data_writes2[] = {
4213 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174214 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334215 "Proxy-Connection: keep-alive\r\n\r\n"),
4216 };
4217
4218 // The proxy, having had more than enough of us, just hangs up.
4219 MockRead data_reads2[] = {
4220 // No credentials.
4221 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4222 };
4223
4224 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4225 data_writes1, arraysize(data_writes1));
4226 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4227 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4228 data_writes2, arraysize(data_writes2));
4229 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4230
bnc87dcefc2017-05-25 12:47:584231 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194232 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334233
4234 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204235 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014236 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334237
4238 const HttpResponseInfo* response = trans->GetResponseInfo();
4239 ASSERT_TRUE(response);
4240 ASSERT_TRUE(response->headers);
4241 EXPECT_TRUE(response->headers->IsKeepAlive());
4242 EXPECT_EQ(407, response->headers->response_code());
4243 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4244 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4245 EXPECT_FALSE(response->auth_challenge);
4246
4247 LoadTimingInfo load_timing_info;
4248 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4249
4250 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014251 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334252
4253 trans.reset();
4254 session->CloseAllConnections();
4255}
4256
4257// Test a proxy auth scheme that allows default credentials and a proxy server
4258// that hangs up when credentials are initially sent, and sends a challenge
4259// again they are retried.
bncd16676a2016-07-20 16:23:014260TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334261 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4262 HttpRequestInfo request;
4263 request.method = "GET";
4264 request.url = GURL("https://www.example.org/");
4265
4266 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594267 session_deps_.proxy_resolution_service =
4268 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
mmenke2a1781d2015-10-07 19:25:334269
Jeremy Roman0579ed62017-08-29 15:56:194270 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334271 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194272 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334273 mock_handler->set_allows_default_credentials(true);
4274 auth_handler_factory->AddMockHandler(mock_handler.release(),
4275 HttpAuth::AUTH_PROXY);
4276 // Add another handler for the second challenge. It supports default
4277 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194278 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334279 mock_handler->set_allows_default_credentials(true);
4280 auth_handler_factory->AddMockHandler(mock_handler.release(),
4281 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484282 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334283
4284 // Add NetLog just so can verify load timing information gets a NetLog ID.
4285 NetLog net_log;
4286 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094287 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334288
4289 // Should try to establish tunnel.
4290 MockWrite data_writes1[] = {
4291 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174292 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334293 "Proxy-Connection: keep-alive\r\n\r\n"),
4294 };
4295
4296 // The proxy responds to the connect with a 407, using a non-persistent
4297 // connection.
4298 MockRead data_reads1[] = {
4299 // No credentials.
4300 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4301 MockRead("Proxy-Authenticate: Mock\r\n"),
4302 MockRead("Proxy-Connection: close\r\n\r\n"),
4303 };
4304
4305 // Since the first connection was closed, need to establish another once given
4306 // credentials.
4307 MockWrite data_writes2[] = {
4308 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174309 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334310 "Proxy-Connection: keep-alive\r\n"
4311 "Proxy-Authorization: auth_token\r\n\r\n"),
4312 };
4313
4314 MockRead data_reads2[] = {
4315 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4316 MockRead("Proxy-Authenticate: Mock\r\n"),
4317 MockRead("Proxy-Connection: close\r\n\r\n"),
4318 };
4319
4320 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4321 data_writes1, arraysize(data_writes1));
4322 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4323 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4324 data_writes2, arraysize(data_writes2));
4325 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4326 SSLSocketDataProvider ssl(ASYNC, OK);
4327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4328
bnc87dcefc2017-05-25 12:47:584329 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194330 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334331
4332 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204333 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014334 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334335
4336 const HttpResponseInfo* response = trans->GetResponseInfo();
4337 ASSERT_TRUE(response);
4338 ASSERT_TRUE(response->headers);
4339 EXPECT_EQ(407, response->headers->response_code());
4340 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4341 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4342 EXPECT_FALSE(response->auth_challenge);
4343
4344 LoadTimingInfo load_timing_info;
4345 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4346
4347 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014348 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334349 response = trans->GetResponseInfo();
4350 ASSERT_TRUE(response);
4351 ASSERT_TRUE(response->headers);
4352 EXPECT_EQ(407, response->headers->response_code());
4353 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4354 EXPECT_TRUE(response->auth_challenge);
4355
4356 trans.reset();
4357 session->CloseAllConnections();
4358}
4359
asankae2257db2016-10-11 22:03:164360// A more nuanced test than GenerateAuthToken test which asserts that
4361// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4362// unnecessarily invalidated, and that if the server co-operates, the
4363// authentication handshake can continue with the same scheme but with a
4364// different identity.
4365TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4366 HttpRequestInfo request;
4367 request.method = "GET";
4368 request.url = GURL("http://www.example.org/");
4369
Jeremy Roman0579ed62017-08-29 15:56:194370 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164371 auth_handler_factory->set_do_init_from_challenge(true);
4372
4373 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194374 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164375 mock_handler->set_allows_default_credentials(true);
4376 mock_handler->set_allows_explicit_credentials(true);
4377 mock_handler->set_connection_based(true);
4378 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4379 auth_handler_factory->AddMockHandler(mock_handler.release(),
4380 HttpAuth::AUTH_SERVER);
4381
4382 // Add another handler for the second challenge. It supports default
4383 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194384 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164385 mock_handler->set_allows_default_credentials(true);
4386 mock_handler->set_allows_explicit_credentials(true);
4387 mock_handler->set_connection_based(true);
4388 auth_handler_factory->AddMockHandler(mock_handler.release(),
4389 HttpAuth::AUTH_SERVER);
4390 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4391
4392 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4393
4394 MockWrite data_writes1[] = {
4395 MockWrite("GET / HTTP/1.1\r\n"
4396 "Host: www.example.org\r\n"
4397 "Connection: keep-alive\r\n\r\n"),
4398 };
4399
4400 MockRead data_reads1[] = {
4401 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4402 "WWW-Authenticate: Mock\r\n"
4403 "Connection: keep-alive\r\n\r\n"),
4404 };
4405
4406 // Identical to data_writes1[]. The AuthHandler encounters a
4407 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4408 // transaction procceds without an authorization header.
4409 MockWrite data_writes2[] = {
4410 MockWrite("GET / HTTP/1.1\r\n"
4411 "Host: www.example.org\r\n"
4412 "Connection: keep-alive\r\n\r\n"),
4413 };
4414
4415 MockRead data_reads2[] = {
4416 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4417 "WWW-Authenticate: Mock\r\n"
4418 "Connection: keep-alive\r\n\r\n"),
4419 };
4420
4421 MockWrite data_writes3[] = {
4422 MockWrite("GET / HTTP/1.1\r\n"
4423 "Host: www.example.org\r\n"
4424 "Connection: keep-alive\r\n"
4425 "Authorization: auth_token\r\n\r\n"),
4426 };
4427
4428 MockRead data_reads3[] = {
4429 MockRead("HTTP/1.1 200 OK\r\n"
4430 "Content-Length: 5\r\n"
4431 "Content-Type: text/plain\r\n"
4432 "Connection: keep-alive\r\n\r\n"
4433 "Hello"),
4434 };
4435
4436 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4437 data_writes1, arraysize(data_writes1));
4438 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4439
4440 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4441 data_writes2, arraysize(data_writes2));
4442 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4443
4444 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4445 data_writes3, arraysize(data_writes3));
4446 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4447
bnc87dcefc2017-05-25 12:47:584448 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194449 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164450
4451 TestCompletionCallback callback;
4452 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4453 EXPECT_THAT(callback.GetResult(rv), IsOk());
4454
4455 const HttpResponseInfo* response = trans->GetResponseInfo();
4456 ASSERT_TRUE(response);
4457 ASSERT_TRUE(response->headers);
4458 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4459
4460 // The following three tests assert that an authentication challenge was
4461 // received and that the stack is ready to respond to the challenge using
4462 // ambient credentials.
4463 EXPECT_EQ(401, response->headers->response_code());
4464 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4465 EXPECT_FALSE(response->auth_challenge);
4466
4467 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4468 EXPECT_THAT(callback.GetResult(rv), IsOk());
4469 response = trans->GetResponseInfo();
4470 ASSERT_TRUE(response);
4471 ASSERT_TRUE(response->headers);
4472
4473 // The following three tests assert that an authentication challenge was
4474 // received and that the stack needs explicit credentials before it is ready
4475 // to respond to the challenge.
4476 EXPECT_EQ(401, response->headers->response_code());
4477 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4478 EXPECT_TRUE(response->auth_challenge);
4479
4480 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4481 EXPECT_THAT(callback.GetResult(rv), IsOk());
4482 response = trans->GetResponseInfo();
4483 ASSERT_TRUE(response);
4484 ASSERT_TRUE(response->headers);
4485 EXPECT_EQ(200, response->headers->response_code());
4486
4487 trans.reset();
4488 session->CloseAllConnections();
4489}
4490
Matt Menked1eb6d42018-01-17 04:54:064491// Proxy resolver that returns a proxy with the same host and port for different
4492// schemes, based on the path of the URL being requests.
4493class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4494 public:
4495 SameProxyWithDifferentSchemesProxyResolver() {}
4496 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4497
4498 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4499
4500 static HostPortPair ProxyHostPortPair() {
4501 return HostPortPair::FromString(ProxyHostPortPairAsString());
4502 }
4503
4504 // ProxyResolver implementation.
4505 int GetProxyForURL(const GURL& url,
4506 ProxyInfo* results,
4507 const CompletionCallback& callback,
4508 std::unique_ptr<Request>* request,
4509 const NetLogWithSource& /*net_log*/) override {
4510 *results = ProxyInfo();
4511 if (url.path() == "/socks4") {
4512 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4513 return OK;
4514 }
4515 if (url.path() == "/socks5") {
4516 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4517 return OK;
4518 }
4519 if (url.path() == "/http") {
4520 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4521 return OK;
4522 }
4523 if (url.path() == "/https") {
4524 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4525 return OK;
4526 }
4527 NOTREACHED();
4528 return ERR_NOT_IMPLEMENTED;
4529 }
4530
4531 private:
4532 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4533};
4534
4535class SameProxyWithDifferentSchemesProxyResolverFactory
4536 : public ProxyResolverFactory {
4537 public:
4538 SameProxyWithDifferentSchemesProxyResolverFactory()
4539 : ProxyResolverFactory(false) {}
4540
4541 int CreateProxyResolver(
4542 const scoped_refptr<ProxyResolverScriptData>& pac_script,
4543 std::unique_ptr<ProxyResolver>* resolver,
4544 const CompletionCallback& callback,
4545 std::unique_ptr<Request>* request) override {
4546 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4547 return OK;
4548 }
4549
4550 private:
4551 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4552};
4553
4554// Check that when different proxy schemes are all applied to a proxy at the
4555// same address, the sonnections are not grouped together. i.e., a request to
4556// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4557// request to foo.com using proxy.com as an HTTP proxy.
4558TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Lily Houghton8c2f97d2018-01-22 05:06:594559 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Matt Menked1eb6d42018-01-17 04:54:064560 std::make_unique<ProxyConfigServiceFixed>(
4561 ProxyConfig::CreateAutoDetect()),
4562 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4563 nullptr);
4564
4565 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4566
4567 MockWrite socks_writes[] = {
4568 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4569 kSOCKS4OkRequestLocalHostPort80Length),
4570 MockWrite(SYNCHRONOUS,
4571 "GET /socks4 HTTP/1.1\r\n"
4572 "Host: test\r\n"
4573 "Connection: keep-alive\r\n\r\n"),
4574 };
4575 MockRead socks_reads[] = {
4576 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4577 MockRead("HTTP/1.0 200 OK\r\n"
4578 "Connection: keep-alive\r\n"
4579 "Content-Length: 15\r\n\r\n"
4580 "SOCKS4 Response"),
4581 };
4582 StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
4583 socks_writes, arraysize(socks_writes));
4584 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4585
4586 const char kSOCKS5Request[] = {
4587 0x05, // Version
4588 0x01, // Command (CONNECT)
4589 0x00, // Reserved
4590 0x03, // Address type (DOMAINNAME)
4591 0x04, // Length of domain (4)
4592 't', 'e', 's', 't', // Domain string
4593 0x00, 0x50, // 16-bit port (80)
4594 };
4595 MockWrite socks5_writes[] = {
4596 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4597 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4598 MockWrite(SYNCHRONOUS,
4599 "GET /socks5 HTTP/1.1\r\n"
4600 "Host: test\r\n"
4601 "Connection: keep-alive\r\n\r\n"),
4602 };
4603 MockRead socks5_reads[] = {
4604 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4605 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4606 MockRead("HTTP/1.0 200 OK\r\n"
4607 "Connection: keep-alive\r\n"
4608 "Content-Length: 15\r\n\r\n"
4609 "SOCKS5 Response"),
4610 };
4611 StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
4612 socks5_writes, arraysize(socks5_writes));
4613 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4614
4615 MockWrite http_writes[] = {
4616 MockWrite(SYNCHRONOUS,
4617 "GET http://test/http HTTP/1.1\r\n"
4618 "Host: test\r\n"
4619 "Proxy-Connection: keep-alive\r\n\r\n"),
4620 };
4621 MockRead http_reads[] = {
4622 MockRead("HTTP/1.1 200 OK\r\n"
4623 "Proxy-Connection: keep-alive\r\n"
4624 "Content-Length: 13\r\n\r\n"
4625 "HTTP Response"),
4626 };
4627 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
4628 http_writes, arraysize(http_writes));
4629 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4630
4631 MockWrite https_writes[] = {
4632 MockWrite(SYNCHRONOUS,
4633 "GET http://test/https HTTP/1.1\r\n"
4634 "Host: test\r\n"
4635 "Proxy-Connection: keep-alive\r\n\r\n"),
4636 };
4637 MockRead https_reads[] = {
4638 MockRead("HTTP/1.1 200 OK\r\n"
4639 "Proxy-Connection: keep-alive\r\n"
4640 "Content-Length: 14\r\n\r\n"
4641 "HTTPS Response"),
4642 };
4643 StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
4644 https_writes, arraysize(https_writes));
4645 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4646 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4647 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4648
4649 struct TestCase {
4650 GURL url;
4651 std::string expected_response;
4652 // How many idle sockets there should be in the SOCKS proxy socket pool
4653 // after the test.
4654 int expected_idle_socks_sockets;
4655 // How many idle sockets there should be in the HTTP proxy socket pool after
4656 // the test.
4657 int expected_idle_http_sockets;
4658 } const kTestCases[] = {
4659 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4660 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4661 {GURL("http://test/http"), "HTTP Response", 2, 1},
4662 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4663 };
4664
4665 for (const auto& test_case : kTestCases) {
4666 HttpRequestInfo request;
4667 request.method = "GET";
4668 request.url = test_case.url;
4669 std::unique_ptr<HttpNetworkTransaction> trans =
4670 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4671 session.get());
4672 TestCompletionCallback callback;
4673 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4674 EXPECT_THAT(callback.GetResult(rv), IsOk());
4675
4676 const HttpResponseInfo* response = trans->GetResponseInfo();
4677 ASSERT_TRUE(response);
4678 ASSERT_TRUE(response->headers);
4679 EXPECT_EQ(200, response->headers->response_code());
4680 std::string response_data;
4681 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4682 EXPECT_EQ(test_case.expected_response, response_data);
4683
4684 // Return the socket to the socket pool, so can make sure it's not used for
4685 // the next requests.
4686 trans.reset();
4687 base::RunLoop().RunUntilIdle();
4688
4689 // Check the number of idle sockets in the pool, to make sure that used
4690 // sockets are indeed being returned to the socket pool. If each request
4691 // doesn't return an idle socket to the pool, the test would incorrectly
4692 // pass.
4693 EXPECT_EQ(
4694 test_case.expected_idle_socks_sockets,
4695 session
4696 ->GetSocketPoolForSOCKSProxy(
4697 HttpNetworkSession::NORMAL_SOCKET_POOL,
4698 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4699 ->IdleSocketCount());
4700 EXPECT_EQ(
4701 test_case.expected_idle_http_sockets,
4702 session
4703 ->GetSocketPoolForHTTPProxy(
4704 HttpNetworkSession::NORMAL_SOCKET_POOL,
4705 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4706 ->IdleSocketCount());
4707 }
4708}
4709
[email protected]029c83b62013-01-24 05:28:204710// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014711TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204712 HttpRequestInfo request1;
4713 request1.method = "GET";
bncce36dca22015-04-21 22:11:234714 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204715
4716 HttpRequestInfo request2;
4717 request2.method = "GET";
bncce36dca22015-04-21 22:11:234718 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204719
4720 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594721 session_deps_.proxy_resolution_service =
4722 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514723 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074724 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094725 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204726
4727 // Since we have proxy, should try to establish tunnel.
4728 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174729 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4730 "Host: www.example.org:443\r\n"
4731 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204732
rsleevidb16bb02015-11-12 23:47:174733 MockWrite("GET /1 HTTP/1.1\r\n"
4734 "Host: www.example.org\r\n"
4735 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204736
rsleevidb16bb02015-11-12 23:47:174737 MockWrite("GET /2 HTTP/1.1\r\n"
4738 "Host: www.example.org\r\n"
4739 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204740 };
4741
4742 // The proxy responds to the connect with a 407, using a persistent
4743 // connection.
4744 MockRead data_reads1[] = {
4745 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4746
4747 MockRead("HTTP/1.1 200 OK\r\n"),
4748 MockRead("Content-Length: 1\r\n\r\n"),
4749 MockRead(SYNCHRONOUS, "1"),
4750
4751 MockRead("HTTP/1.1 200 OK\r\n"),
4752 MockRead("Content-Length: 2\r\n\r\n"),
4753 MockRead(SYNCHRONOUS, "22"),
4754 };
4755
4756 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4757 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074758 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204759 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204761
4762 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584763 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194764 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204765
4766 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204768
4769 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014770 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204771
4772 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524773 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474774 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524775 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204776 EXPECT_EQ(1, response1->headers->GetContentLength());
4777
4778 LoadTimingInfo load_timing_info1;
4779 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4780 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4781
4782 trans1.reset();
4783
4784 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584785 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194786 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204787
4788 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204790
4791 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014792 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204793
4794 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524795 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474796 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524797 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204798 EXPECT_EQ(2, response2->headers->GetContentLength());
4799
4800 LoadTimingInfo load_timing_info2;
4801 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4802 TestLoadTimingReused(load_timing_info2);
4803
4804 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4805
4806 trans2.reset();
4807 session->CloseAllConnections();
4808}
4809
4810// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014811TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[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");
[email protected]029c83b62013-01-24 05:28:204815
4816 HttpRequestInfo request2;
4817 request2.method = "GET";
bncce36dca22015-04-21 22:11:234818 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204819
4820 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594821 session_deps_.proxy_resolution_service =
4822 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514823 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074824 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204826
4827 // Since we have proxy, should try to establish tunnel.
4828 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174829 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4830 "Host: www.example.org:443\r\n"
4831 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204832
rsleevidb16bb02015-11-12 23:47:174833 MockWrite("GET /1 HTTP/1.1\r\n"
4834 "Host: www.example.org\r\n"
4835 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204836
rsleevidb16bb02015-11-12 23:47:174837 MockWrite("GET /2 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 };
4841
4842 // The proxy responds to the connect with a 407, using a persistent
4843 // connection.
4844 MockRead data_reads1[] = {
4845 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4846
4847 MockRead("HTTP/1.1 200 OK\r\n"),
4848 MockRead("Content-Length: 1\r\n\r\n"),
4849 MockRead(SYNCHRONOUS, "1"),
4850
4851 MockRead("HTTP/1.1 200 OK\r\n"),
4852 MockRead("Content-Length: 2\r\n\r\n"),
4853 MockRead(SYNCHRONOUS, "22"),
4854 };
4855
4856 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4857 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074858 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204859 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204861
4862 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584863 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194864 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204865
4866 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204868
4869 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014870 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204871
4872 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524873 ASSERT_TRUE(response1);
4874 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204875 EXPECT_EQ(1, response1->headers->GetContentLength());
4876
4877 LoadTimingInfo load_timing_info1;
4878 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4879 TestLoadTimingNotReusedWithPac(load_timing_info1,
4880 CONNECT_TIMING_HAS_SSL_TIMES);
4881
4882 trans1.reset();
4883
4884 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584885 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194886 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204887
4888 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204890
4891 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014892 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204893
4894 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524895 ASSERT_TRUE(response2);
4896 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204897 EXPECT_EQ(2, response2->headers->GetContentLength());
4898
4899 LoadTimingInfo load_timing_info2;
4900 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4901 TestLoadTimingReusedWithPac(load_timing_info2);
4902
4903 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4904
4905 trans2.reset();
4906 session->CloseAllConnections();
4907}
4908
[email protected]2df19bb2010-08-25 20:13:464909// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014910TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274911 HttpRequestInfo request;
4912 request.method = "GET";
bncce36dca22015-04-21 22:11:234913 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274914
[email protected]2df19bb2010-08-25 20:13:464915 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594916 session_deps_.proxy_resolution_service =
4917 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514918 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074919 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464921
[email protected]2df19bb2010-08-25 20:13:464922 // Since we have proxy, should use full url
4923 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234924 MockWrite(
4925 "GET http://www.example.org/ HTTP/1.1\r\n"
4926 "Host: www.example.org\r\n"
4927 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464928 };
4929
4930 MockRead data_reads1[] = {
4931 MockRead("HTTP/1.1 200 OK\r\n"),
4932 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4933 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064934 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464935 };
4936
4937 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4938 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074939 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064940 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464942
[email protected]49639fa2011-12-20 23:22:414943 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464944
bnc691fda62016-08-12 00:43:164945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504946
bnc691fda62016-08-12 00:43:164947 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464949
4950 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014951 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464952
[email protected]58e32bb2013-01-21 18:23:254953 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164954 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254955 TestLoadTimingNotReused(load_timing_info,
4956 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4957
bnc691fda62016-08-12 00:43:164958 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524959 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464960
tbansal2ecbbc72016-10-06 17:15:474961 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464962 EXPECT_TRUE(response->headers->IsKeepAlive());
4963 EXPECT_EQ(200, response->headers->response_code());
4964 EXPECT_EQ(100, response->headers->GetContentLength());
4965 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4966
4967 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524968 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464969}
4970
[email protected]7642b5ae2010-09-01 20:55:174971// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014972TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274973 HttpRequestInfo request;
4974 request.method = "GET";
bncce36dca22015-04-21 22:11:234975 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274976
[email protected]7642b5ae2010-09-01 20:55:174977 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594978 session_deps_.proxy_resolution_service =
4979 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514980 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074981 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174983
bncce36dca22015-04-21 22:11:234984 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414985 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454986 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414987 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174988
bnc42331402016-07-25 13:36:154989 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414990 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174991 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414992 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174993 };
4994
rch8e6c6c42015-05-01 14:05:134995 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4996 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074997 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174998
[email protected]8ddf8322012-02-23 18:08:064999 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365000 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175002
[email protected]49639fa2011-12-20 23:22:415003 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175004
bnc691fda62016-08-12 00:43:165005 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505006
bnc691fda62016-08-12 00:43:165007 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175009
5010 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015011 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175012
[email protected]58e32bb2013-01-21 18:23:255013 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165014 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255015 TestLoadTimingNotReused(load_timing_info,
5016 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5017
bnc691fda62016-08-12 00:43:165018 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525019 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475020 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525021 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025022 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175023
5024 std::string response_data;
bnc691fda62016-08-12 00:43:165025 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235026 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175027}
5028
[email protected]1c173852014-06-19 12:51:505029// Verifies that a session which races and wins against the owning transaction
5030// (completing prior to host resolution), doesn't fail the transaction.
5031// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015032TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505033 HttpRequestInfo request;
5034 request.method = "GET";
bncce36dca22015-04-21 22:11:235035 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:505036
5037 // Configure SPDY proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595038 session_deps_.proxy_resolution_service =
5039 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515040 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505041 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505043
bncce36dca22015-04-21 22:11:235044 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:415045 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455046 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415047 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505048
bnc42331402016-07-25 13:36:155049 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415050 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505051 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415052 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505053 };
5054
rch8e6c6c42015-05-01 14:05:135055 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5056 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:505057 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5058
5059 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365060 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5062
5063 TestCompletionCallback callback1;
5064
bnc691fda62016-08-12 00:43:165065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505066
5067 // Stall the hostname resolution begun by the transaction.
5068 session_deps_.host_resolver->set_synchronous_mode(false);
5069 session_deps_.host_resolver->set_ondemand_mode(true);
5070
bnc691fda62016-08-12 00:43:165071 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505073
5074 // Race a session to the proxy, which completes first.
5075 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045076 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5077 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505078 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525079 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505080
5081 // Unstall the resolution begun by the transaction.
5082 session_deps_.host_resolver->set_ondemand_mode(true);
5083 session_deps_.host_resolver->ResolveAllPending();
5084
5085 EXPECT_FALSE(callback1.have_result());
5086 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015087 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505088
bnc691fda62016-08-12 00:43:165089 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525090 ASSERT_TRUE(response);
5091 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025092 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505093
5094 std::string response_data;
bnc691fda62016-08-12 00:43:165095 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505096 EXPECT_EQ(kUploadData, response_data);
5097}
5098
[email protected]dc7bd1c52010-11-12 00:01:135099// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015100TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275101 HttpRequestInfo request;
5102 request.method = "GET";
bncce36dca22015-04-21 22:11:235103 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275104
[email protected]79cb5c12011-09-12 13:12:045105 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595106 session_deps_.proxy_resolution_service =
5107 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515108 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075109 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095110 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135111
[email protected]dc7bd1c52010-11-12 00:01:135112 // The first request will be a bare GET, the second request will be a
5113 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455114 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:415115 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:495116 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:385117 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135118 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465119 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135120 };
bncdf80d44fd2016-07-15 20:27:415121 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
5122 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
5123 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:135124 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415125 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135126 };
5127
5128 // The first response is a 407 proxy authentication challenge, and the second
5129 // response will be a 200 response since the second request includes a valid
5130 // Authorization header.
5131 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465132 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135133 };
bnc42331402016-07-25 13:36:155134 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:235135 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:415136 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5137 SpdySerializedFrame body_authentication(
5138 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:155139 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415140 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135141 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415142 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465143 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415144 CreateMockRead(resp_data, 4),
5145 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135146 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135147 };
5148
rch8e6c6c42015-05-01 14:05:135149 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5150 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075151 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135152
[email protected]8ddf8322012-02-23 18:08:065153 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365154 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135156
[email protected]49639fa2011-12-20 23:22:415157 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135158
bnc691fda62016-08-12 00:43:165159 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135160
bnc691fda62016-08-12 00:43:165161 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135163
5164 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015165 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135166
bnc691fda62016-08-12 00:43:165167 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135168
wezca1070932016-05-26 20:30:525169 ASSERT_TRUE(response);
5170 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135171 EXPECT_EQ(407, response->headers->response_code());
5172 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435173 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135174
[email protected]49639fa2011-12-20 23:22:415175 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135176
bnc691fda62016-08-12 00:43:165177 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135179
5180 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015181 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135182
bnc691fda62016-08-12 00:43:165183 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135184
wezca1070932016-05-26 20:30:525185 ASSERT_TRUE(response_restart);
5186 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135187 EXPECT_EQ(200, response_restart->headers->response_code());
5188 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525189 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135190}
5191
[email protected]d9da5fe2010-10-13 22:37:165192// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015193TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275194 HttpRequestInfo request;
5195 request.method = "GET";
bncce36dca22015-04-21 22:11:235196 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275197
[email protected]d9da5fe2010-10-13 22:37:165198 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595199 session_deps_.proxy_resolution_service =
5200 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515201 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075202 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095203 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165204
bnc691fda62016-08-12 00:43:165205 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165206
bncce36dca22015-04-21 22:11:235207 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415208 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235209 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5210 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165211
bncce36dca22015-04-21 22:11:235212 const char get[] =
5213 "GET / HTTP/1.1\r\n"
5214 "Host: www.example.org\r\n"
5215 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415216 SpdySerializedFrame wrapped_get(
5217 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:155218 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165219 const char resp[] = "HTTP/1.1 200 OK\r\n"
5220 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415221 SpdySerializedFrame wrapped_get_resp(
5222 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
5223 SpdySerializedFrame wrapped_body(
5224 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
5225 SpdySerializedFrame window_update(
5226 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045227
5228 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415229 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5230 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045231 };
5232
[email protected]d9da5fe2010-10-13 22:37:165233 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415234 CreateMockRead(conn_resp, 1, ASYNC),
5235 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5236 CreateMockRead(wrapped_body, 4, ASYNC),
5237 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135238 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165239 };
5240
rch8e6c6c42015-05-01 14:05:135241 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5242 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075243 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165244
[email protected]8ddf8322012-02-23 18:08:065245 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365246 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075247 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065248 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165250
[email protected]49639fa2011-12-20 23:22:415251 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165252
bnc691fda62016-08-12 00:43:165253 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165255
5256 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015257 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165258
[email protected]58e32bb2013-01-21 18:23:255259 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165260 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255261 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5262
bnc691fda62016-08-12 00:43:165263 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525264 ASSERT_TRUE(response);
5265 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165266 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5267
5268 std::string response_data;
bnc691fda62016-08-12 00:43:165269 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165270 EXPECT_EQ("1234567890", response_data);
5271}
5272
5273// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015274TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5275 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385276
[email protected]cb9bf6ca2011-01-28 13:15:275277 HttpRequestInfo request;
5278 request.method = "GET";
bncce36dca22015-04-21 22:11:235279 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275280
[email protected]d9da5fe2010-10-13 22:37:165281 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595282 session_deps_.proxy_resolution_service =
5283 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515284 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075285 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165287
bnc691fda62016-08-12 00:43:165288 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165289
bncce36dca22015-04-21 22:11:235290 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415291 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235292 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5293 // fetch https://www.example.org/ via SPDY
5294 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415295 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495296 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415297 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155298 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415299 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155300 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415301 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025302 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415303 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5304 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025305 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415306 SpdySerializedFrame window_update_get_resp(
5307 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5308 SpdySerializedFrame window_update_body(
5309 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045310
5311 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415312 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5313 CreateMockWrite(window_update_get_resp, 6),
5314 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045315 };
5316
[email protected]d9da5fe2010-10-13 22:37:165317 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415318 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095319 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415320 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5321 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135322 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165323 };
5324
rch32320842015-05-16 15:57:095325 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5326 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075327 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165328
[email protected]8ddf8322012-02-23 18:08:065329 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365330 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065332 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365333 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165335
[email protected]49639fa2011-12-20 23:22:415336 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165337
bnc691fda62016-08-12 00:43:165338 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015339 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165340
rch32320842015-05-16 15:57:095341 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555342 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095343 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595344 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165345 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015346 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165347
[email protected]58e32bb2013-01-21 18:23:255348 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165349 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255350 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5351
bnc691fda62016-08-12 00:43:165352 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525353 ASSERT_TRUE(response);
5354 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025355 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165356
5357 std::string response_data;
bnc691fda62016-08-12 00:43:165358 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235359 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165360}
5361
5362// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015363TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275364 HttpRequestInfo request;
5365 request.method = "GET";
bncce36dca22015-04-21 22:11:235366 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275367
[email protected]d9da5fe2010-10-13 22:37:165368 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595369 session_deps_.proxy_resolution_service =
5370 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515371 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075372 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165374
bnc691fda62016-08-12 00:43:165375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165376
bncce36dca22015-04-21 22:11:235377 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415378 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235379 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415380 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085381 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165382
5383 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415384 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165385 };
5386
bnc42331402016-07-25 13:36:155387 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415388 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165389 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415390 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165391 };
5392
rch8e6c6c42015-05-01 14:05:135393 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5394 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075395 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165396
[email protected]8ddf8322012-02-23 18:08:065397 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365398 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065400 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365401 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075402 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165403
[email protected]49639fa2011-12-20 23:22:415404 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165405
bnc691fda62016-08-12 00:43:165406 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165408
5409 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015410 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165411
ttuttle960fcbf2016-04-19 13:26:325412 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165413}
5414
[email protected]f6c63db52013-02-02 00:35:225415// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5416// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015417TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225418 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5419 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595420 session_deps_.proxy_resolution_service =
5421 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515422 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075423 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095424 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505425 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225426
5427 HttpRequestInfo request1;
5428 request1.method = "GET";
bncce36dca22015-04-21 22:11:235429 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225430 request1.load_flags = 0;
5431
5432 HttpRequestInfo request2;
5433 request2.method = "GET";
bncce36dca22015-04-21 22:11:235434 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225435 request2.load_flags = 0;
5436
bncce36dca22015-04-21 22:11:235437 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415438 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235439 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155440 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225441
bncce36dca22015-04-21 22:11:235442 // Fetch https://www.example.org/ via HTTP.
5443 const char get1[] =
5444 "GET / HTTP/1.1\r\n"
5445 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225446 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415447 SpdySerializedFrame wrapped_get1(
5448 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225449 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5450 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415451 SpdySerializedFrame wrapped_get_resp1(
5452 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5453 SpdySerializedFrame wrapped_body1(
5454 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5455 SpdySerializedFrame window_update(
5456 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225457
bncce36dca22015-04-21 22:11:235458 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295459 SpdyHeaderBlock connect2_block;
Bence Békybda82952017-10-02 17:35:275460 connect2_block[kHttp2MethodHeader] = "CONNECT";
5461 connect2_block[kHttp2AuthorityHeader] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155462 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5463 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395464
bnc42331402016-07-25 13:36:155465 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225466
bncce36dca22015-04-21 22:11:235467 // Fetch https://mail.example.org/ via HTTP.
5468 const char get2[] =
5469 "GET / HTTP/1.1\r\n"
5470 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225471 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415472 SpdySerializedFrame wrapped_get2(
5473 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225474 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5475 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415476 SpdySerializedFrame wrapped_get_resp2(
5477 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5478 SpdySerializedFrame wrapped_body2(
5479 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225480
5481 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415482 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5483 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225484 };
5485
5486 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415487 CreateMockRead(conn_resp1, 1, ASYNC),
5488 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5489 CreateMockRead(wrapped_body1, 4, ASYNC),
5490 CreateMockRead(conn_resp2, 6, ASYNC),
5491 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5492 CreateMockRead(wrapped_body2, 9, ASYNC),
5493 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225494 };
5495
mmenke11eb5152015-06-09 14:50:505496 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5497 arraysize(spdy_writes));
5498 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225499
5500 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365501 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225503 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225505 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225507
5508 TestCompletionCallback callback;
5509
bnc691fda62016-08-12 00:43:165510 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205511 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015512 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225513
5514 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165515 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225516 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5517
bnc691fda62016-08-12 00:43:165518 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525519 ASSERT_TRUE(response);
5520 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225521 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5522
5523 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295524 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165525 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505526 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225527
bnc691fda62016-08-12 00:43:165528 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205529 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015530 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225531
5532 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165533 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225534 // Even though the SPDY connection is reused, a new tunnelled connection has
5535 // to be created, so the socket's load timing looks like a fresh connection.
5536 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5537
5538 // The requests should have different IDs, since they each are using their own
5539 // separate stream.
5540 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5541
bnc691fda62016-08-12 00:43:165542 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505543 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225544}
5545
5546// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5547// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015548TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225549 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5550 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595551 session_deps_.proxy_resolution_service =
5552 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515553 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075554 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095555 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505556 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225557
5558 HttpRequestInfo request1;
5559 request1.method = "GET";
bncce36dca22015-04-21 22:11:235560 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225561 request1.load_flags = 0;
5562
5563 HttpRequestInfo request2;
5564 request2.method = "GET";
bncce36dca22015-04-21 22:11:235565 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225566 request2.load_flags = 0;
5567
bncce36dca22015-04-21 22:11:235568 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415569 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235570 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155571 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225572
bncce36dca22015-04-21 22:11:235573 // Fetch https://www.example.org/ via HTTP.
5574 const char get1[] =
5575 "GET / HTTP/1.1\r\n"
5576 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225577 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415578 SpdySerializedFrame wrapped_get1(
5579 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225580 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5581 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415582 SpdySerializedFrame wrapped_get_resp1(
5583 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5584 SpdySerializedFrame wrapped_body1(
5585 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5586 SpdySerializedFrame window_update(
5587 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225588
bncce36dca22015-04-21 22:11:235589 // Fetch https://www.example.org/2 via HTTP.
5590 const char get2[] =
5591 "GET /2 HTTP/1.1\r\n"
5592 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225593 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415594 SpdySerializedFrame wrapped_get2(
5595 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225596 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5597 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415598 SpdySerializedFrame wrapped_get_resp2(
5599 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5600 SpdySerializedFrame wrapped_body2(
5601 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225602
5603 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415604 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5605 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225606 };
5607
5608 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415609 CreateMockRead(conn_resp1, 1, ASYNC),
5610 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465611 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415612 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465613 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415614 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225615 };
5616
mmenke11eb5152015-06-09 14:50:505617 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5618 arraysize(spdy_writes));
5619 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225620
5621 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365622 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225624 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225626
5627 TestCompletionCallback callback;
5628
bnc87dcefc2017-05-25 12:47:585629 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195630 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205631 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225633
5634 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015635 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225636
5637 LoadTimingInfo load_timing_info;
5638 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5639 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5640
5641 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525642 ASSERT_TRUE(response);
5643 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225644 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5645
5646 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295647 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505648 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225649 trans.reset();
5650
bnc87dcefc2017-05-25 12:47:585651 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195652 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205653 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225655
[email protected]f6c63db52013-02-02 00:35:225656 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015657 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225658
5659 LoadTimingInfo load_timing_info2;
5660 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5661 TestLoadTimingReused(load_timing_info2);
5662
5663 // The requests should have the same ID.
5664 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5665
[email protected]90499482013-06-01 00:39:505666 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225667}
5668
5669// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5670// Proxy to different servers.
bncd16676a2016-07-20 16:23:015671TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225672 // Configure against https proxy server "proxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595673 session_deps_.proxy_resolution_service =
5674 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515675 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075676 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095677 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505678 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225679
5680 HttpRequestInfo request1;
5681 request1.method = "GET";
bncce36dca22015-04-21 22:11:235682 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225683 request1.load_flags = 0;
5684
5685 HttpRequestInfo request2;
5686 request2.method = "GET";
bncce36dca22015-04-21 22:11:235687 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225688 request2.load_flags = 0;
5689
bncce36dca22015-04-21 22:11:235690 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265691 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235692 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415693 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155694 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5695 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415696 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385697 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225698
bncce36dca22015-04-21 22:11:235699 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265700 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235701 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415702 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155703 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5704 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415705 SpdySerializedFrame body2(
5706 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225707
5708 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415709 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225710 };
5711
5712 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415713 CreateMockRead(get_resp1, 1, ASYNC),
5714 CreateMockRead(body1, 2, ASYNC),
5715 CreateMockRead(get_resp2, 4, ASYNC),
5716 CreateMockRead(body2, 5, ASYNC),
5717 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225718 };
5719
mmenke11eb5152015-06-09 14:50:505720 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5721 arraysize(spdy_writes));
5722 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225723
5724 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365725 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505726 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225727
5728 TestCompletionCallback callback;
5729
bnc87dcefc2017-05-25 12:47:585730 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195731 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205732 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015733 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225734
5735 LoadTimingInfo load_timing_info;
5736 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5737 TestLoadTimingNotReused(load_timing_info,
5738 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5739
5740 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525741 ASSERT_TRUE(response);
5742 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025743 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225744
5745 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295746 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505747 rv = trans->Read(buf.get(), 256, callback.callback());
5748 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225749 // Delete the first request, so the second one can reuse the socket.
5750 trans.reset();
5751
bnc691fda62016-08-12 00:43:165752 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205753 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015754 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225755
5756 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165757 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225758 TestLoadTimingReused(load_timing_info2);
5759
5760 // The requests should have the same ID.
5761 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5762
bnc691fda62016-08-12 00:43:165763 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505764 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225765}
5766
[email protected]2df19bb2010-08-25 20:13:465767// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015768TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465769 HttpRequestInfo request;
5770 request.method = "GET";
bncce36dca22015-04-21 22:11:235771 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465772 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295773 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465774
[email protected]79cb5c12011-09-12 13:12:045775 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595776 session_deps_.proxy_resolution_service =
5777 ProxyResolutionService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515778 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075779 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275781
[email protected]2df19bb2010-08-25 20:13:465782 // Since we have proxy, should use full url
5783 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165784 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5785 "Host: www.example.org\r\n"
5786 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465787
bnc691fda62016-08-12 00:43:165788 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235789 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165790 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5791 "Host: www.example.org\r\n"
5792 "Proxy-Connection: keep-alive\r\n"
5793 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465794 };
5795
5796 // The proxy responds to the GET with a 407, using a persistent
5797 // connection.
5798 MockRead data_reads1[] = {
5799 // No credentials.
5800 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5801 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5802 MockRead("Proxy-Connection: keep-alive\r\n"),
5803 MockRead("Content-Length: 0\r\n\r\n"),
5804
5805 MockRead("HTTP/1.1 200 OK\r\n"),
5806 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5807 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065808 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465809 };
5810
5811 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5812 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065814 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075815 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465816
[email protected]49639fa2011-12-20 23:22:415817 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465818
bnc691fda62016-08-12 00:43:165819 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505820
bnc691fda62016-08-12 00:43:165821 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465823
5824 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015825 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465826
[email protected]58e32bb2013-01-21 18:23:255827 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165828 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255829 TestLoadTimingNotReused(load_timing_info,
5830 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5831
bnc691fda62016-08-12 00:43:165832 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525833 ASSERT_TRUE(response);
5834 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465835 EXPECT_EQ(407, response->headers->response_code());
5836 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435837 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465838
[email protected]49639fa2011-12-20 23:22:415839 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465840
bnc691fda62016-08-12 00:43:165841 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465843
5844 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015845 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465846
[email protected]58e32bb2013-01-21 18:23:255847 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165848 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255849 // Retrying with HTTP AUTH is considered to be reusing a socket.
5850 TestLoadTimingReused(load_timing_info);
5851
bnc691fda62016-08-12 00:43:165852 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525853 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465854
5855 EXPECT_TRUE(response->headers->IsKeepAlive());
5856 EXPECT_EQ(200, response->headers->response_code());
5857 EXPECT_EQ(100, response->headers->GetContentLength());
5858 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5859
5860 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525861 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465862}
5863
[email protected]23e482282013-06-14 16:08:025864void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085865 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425866 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085867 request.method = "GET";
bncce36dca22015-04-21 22:11:235868 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085869
[email protected]cb9bf6ca2011-01-28 13:15:275870 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595871 session_deps_.proxy_resolution_service =
5872 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275874
[email protected]c744cf22009-02-27 07:28:085875 // Since we have proxy, should try to establish tunnel.
5876 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175877 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5878 "Host: www.example.org:443\r\n"
5879 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085880 };
5881
5882 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235883 status, MockRead("Content-Length: 10\r\n\r\n"),
5884 // No response body because the test stops reading here.
5885 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085886 };
5887
[email protected]31a2bfe2010-02-09 08:03:395888 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5889 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075890 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085891
[email protected]49639fa2011-12-20 23:22:415892 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085893
bnc691fda62016-08-12 00:43:165894 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505895
tfarina42834112016-09-22 13:38:205896 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085898
5899 rv = callback.WaitForResult();
5900 EXPECT_EQ(expected_status, rv);
5901}
5902
[email protected]23e482282013-06-14 16:08:025903void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235904 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085905 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425906 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085907}
5908
bncd16676a2016-07-20 16:23:015909TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085910 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5911}
5912
bncd16676a2016-07-20 16:23:015913TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085914 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5915}
5916
bncd16676a2016-07-20 16:23:015917TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085918 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5919}
5920
bncd16676a2016-07-20 16:23:015921TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085922 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5923}
5924
bncd16676a2016-07-20 16:23:015925TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085926 ConnectStatusHelper(
5927 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5928}
5929
bncd16676a2016-07-20 16:23:015930TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085931 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5932}
5933
bncd16676a2016-07-20 16:23:015934TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085935 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5936}
5937
bncd16676a2016-07-20 16:23:015938TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085939 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5940}
5941
bncd16676a2016-07-20 16:23:015942TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085943 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5944}
5945
bncd16676a2016-07-20 16:23:015946TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085947 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5948}
5949
bncd16676a2016-07-20 16:23:015950TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085951 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5952}
5953
bncd16676a2016-07-20 16:23:015954TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085955 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5956}
5957
bncd16676a2016-07-20 16:23:015958TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085959 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5960}
5961
bncd16676a2016-07-20 16:23:015962TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085963 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5964}
5965
bncd16676a2016-07-20 16:23:015966TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085967 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5968}
5969
bncd16676a2016-07-20 16:23:015970TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085971 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5972}
5973
bncd16676a2016-07-20 16:23:015974TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375975 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5976}
5977
bncd16676a2016-07-20 16:23:015978TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085979 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5980}
5981
bncd16676a2016-07-20 16:23:015982TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085983 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5984}
5985
bncd16676a2016-07-20 16:23:015986TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085987 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5988}
5989
bncd16676a2016-07-20 16:23:015990TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085991 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5992}
5993
bncd16676a2016-07-20 16:23:015994TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085995 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5996}
5997
bncd16676a2016-07-20 16:23:015998TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085999 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6000}
6001
bncd16676a2016-07-20 16:23:016002TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086003 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6004}
6005
bncd16676a2016-07-20 16:23:016006TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086007 ConnectStatusHelperWithExpectedStatus(
6008 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546009 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086010}
6011
bncd16676a2016-07-20 16:23:016012TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086013 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6014}
6015
bncd16676a2016-07-20 16:23:016016TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086017 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6018}
6019
bncd16676a2016-07-20 16:23:016020TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086021 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6022}
6023
bncd16676a2016-07-20 16:23:016024TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086025 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6026}
6027
bncd16676a2016-07-20 16:23:016028TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086029 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6030}
6031
bncd16676a2016-07-20 16:23:016032TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086033 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6034}
6035
bncd16676a2016-07-20 16:23:016036TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086037 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6038}
6039
bncd16676a2016-07-20 16:23:016040TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086041 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6042}
6043
bncd16676a2016-07-20 16:23:016044TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086045 ConnectStatusHelper(
6046 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6047}
6048
bncd16676a2016-07-20 16:23:016049TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086050 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6051}
6052
bncd16676a2016-07-20 16:23:016053TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086054 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6055}
6056
bncd16676a2016-07-20 16:23:016057TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086058 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6059}
6060
bncd16676a2016-07-20 16:23:016061TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086062 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6063}
6064
bncd16676a2016-07-20 16:23:016065TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086066 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6067}
6068
bncd16676a2016-07-20 16:23:016069TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086070 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6071}
6072
bncd16676a2016-07-20 16:23:016073TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086074 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6075}
6076
[email protected]038e9a32008-10-08 22:40:166077// Test the flow when both the proxy server AND origin server require
6078// authentication. Again, this uses basic auth for both since that is
6079// the simplest to mock.
bncd16676a2016-07-20 16:23:016080TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276081 HttpRequestInfo request;
6082 request.method = "GET";
bncce36dca22015-04-21 22:11:236083 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276084
[email protected]038e9a32008-10-08 22:40:166085 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596086 session_deps_.proxy_resolution_service =
6087 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:096088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076089
bnc691fda62016-08-12 00:43:166090 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166091
[email protected]f9ee6b52008-11-08 06:46:236092 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236093 MockWrite(
6094 "GET http://www.example.org/ HTTP/1.1\r\n"
6095 "Host: www.example.org\r\n"
6096 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236097 };
6098
[email protected]038e9a32008-10-08 22:40:166099 MockRead data_reads1[] = {
6100 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6101 // Give a couple authenticate options (only the middle one is actually
6102 // supported).
[email protected]22927ad2009-09-21 19:56:196103 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166104 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6105 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6106 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6107 // Large content-length -- won't matter, as connection will be reset.
6108 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066109 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166110 };
6111
bnc691fda62016-08-12 00:43:166112 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166113 // request we should be issuing -- the final header line contains the
6114 // proxy's credentials.
6115 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236116 MockWrite(
6117 "GET http://www.example.org/ HTTP/1.1\r\n"
6118 "Host: www.example.org\r\n"
6119 "Proxy-Connection: keep-alive\r\n"
6120 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166121 };
6122
6123 // Now the proxy server lets the request pass through to origin server.
6124 // The origin server responds with a 401.
6125 MockRead data_reads2[] = {
6126 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6127 // Note: We are using the same realm-name as the proxy server. This is
6128 // completely valid, as realms are unique across hosts.
6129 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6130 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6131 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066132 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166133 };
6134
bnc691fda62016-08-12 00:43:166135 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166136 // the credentials for both the proxy and origin server.
6137 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236138 MockWrite(
6139 "GET http://www.example.org/ HTTP/1.1\r\n"
6140 "Host: www.example.org\r\n"
6141 "Proxy-Connection: keep-alive\r\n"
6142 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6143 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166144 };
6145
6146 // Lastly we get the desired content.
6147 MockRead data_reads3[] = {
6148 MockRead("HTTP/1.0 200 OK\r\n"),
6149 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6150 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066151 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166152 };
6153
[email protected]31a2bfe2010-02-09 08:03:396154 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6155 data_writes1, arraysize(data_writes1));
6156 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6157 data_writes2, arraysize(data_writes2));
6158 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6159 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076160 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6161 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6162 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166163
[email protected]49639fa2011-12-20 23:22:416164 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166165
tfarina42834112016-09-22 13:38:206166 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016167 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166168
6169 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016170 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166171
bnc691fda62016-08-12 00:43:166172 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526173 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046174 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166175
[email protected]49639fa2011-12-20 23:22:416176 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166177
bnc691fda62016-08-12 00:43:166178 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016179 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166180
6181 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016182 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166183
bnc691fda62016-08-12 00:43:166184 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526185 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046186 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166187
[email protected]49639fa2011-12-20 23:22:416188 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166189
bnc691fda62016-08-12 00:43:166190 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6191 callback3.callback());
robpercival214763f2016-07-01 23:27:016192 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166193
6194 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016195 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166196
bnc691fda62016-08-12 00:43:166197 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526198 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166199 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166200}
[email protected]4ddaf2502008-10-23 18:26:196201
[email protected]ea9dc9a2009-09-05 00:43:326202// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6203// can't hook into its internals to cause it to generate predictable NTLM
6204// authorization headers.
6205#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376206// The NTLM authentication unit tests are based on known test data from the
6207// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6208// flow rather than the implementation of the NTLM protocol. See net/ntlm
6209// for the implementation and testing of the protocol.
6210//
6211// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296212
6213// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556214TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426215 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246216 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556217 request.url = GURL("https://server/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:546218
6219 // Ensure load is not disrupted by flags which suppress behaviour specific
6220 // to other auth schemes.
6221 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246222
Zentaro Kavanagh6ccee512017-09-28 18:34:096223 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6224 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276226
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376227 // Generate the NTLM messages based on known test data.
6228 std::string negotiate_msg;
6229 std::string challenge_msg;
6230 std::string authenticate_msg;
6231 base::Base64Encode(
6232 base::StringPiece(
6233 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6234 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6235 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556236 base::Base64Encode(
6237 base::StringPiece(
6238 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6239 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6240 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376241 base::Base64Encode(
6242 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096243 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556244 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6245 arraysize(
6246 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376247 &authenticate_msg);
6248
[email protected]3f918782009-02-28 01:29:246249 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556250 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6251 "Host: server\r\n"
6252 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246253 };
6254
6255 MockRead data_reads1[] = {
6256 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046257 // Negotiate and NTLM are often requested together. However, we only want
6258 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6259 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246260 MockRead("WWW-Authenticate: NTLM\r\n"),
6261 MockRead("Connection: close\r\n"),
6262 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366263 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246264 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246265 };
6266
6267 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166268 // After restarting with a null identity, this is the
6269 // request we should be issuing -- the final header line contains a Type
6270 // 1 message.
6271 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556272 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166273 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376274 "Authorization: NTLM "),
6275 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246276
bnc691fda62016-08-12 00:43:166277 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376278 // (using correct credentials). The second request continues on the
6279 // same connection.
bnc691fda62016-08-12 00:43:166280 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556281 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166282 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376283 "Authorization: NTLM "),
6284 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246285 };
6286
6287 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026288 // The origin server responds with a Type 2 message.
6289 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376290 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6291 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026292 MockRead("Content-Type: text/html\r\n\r\n"),
6293 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246294
Bence Béky1e4ef192017-09-18 19:58:026295 // Lastly we get the desired content.
6296 MockRead("HTTP/1.1 200 OK\r\n"),
6297 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6298 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246299 };
6300
[email protected]31a2bfe2010-02-09 08:03:396301 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6302 data_writes1, arraysize(data_writes1));
6303 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6304 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076305 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6306 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246307
Bence Béky83eb3512017-09-05 12:56:096308 SSLSocketDataProvider ssl1(ASYNC, OK);
6309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6310 SSLSocketDataProvider ssl2(ASYNC, OK);
6311 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6312
[email protected]49639fa2011-12-20 23:22:416313 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246314
bnc691fda62016-08-12 00:43:166315 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506316
tfarina42834112016-09-22 13:38:206317 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246319
6320 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016321 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246322
bnc691fda62016-08-12 00:43:166323 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226324
bnc691fda62016-08-12 00:43:166325 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526326 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046327 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246328
[email protected]49639fa2011-12-20 23:22:416329 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256330
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376331 rv = trans.RestartWithAuth(
6332 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6333 callback2.callback());
robpercival214763f2016-07-01 23:27:016334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256335
6336 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016337 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256338
bnc691fda62016-08-12 00:43:166339 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256340
bnc691fda62016-08-12 00:43:166341 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526342 ASSERT_TRUE(response);
6343 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256344
[email protected]49639fa2011-12-20 23:22:416345 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246346
bnc691fda62016-08-12 00:43:166347 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246349
[email protected]0757e7702009-03-27 04:00:226350 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016351 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246352
bnc691fda62016-08-12 00:43:166353 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526354 ASSERT_TRUE(response);
6355 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026356 EXPECT_EQ(14, response->headers->GetContentLength());
6357
6358 std::string response_data;
6359 rv = ReadTransaction(&trans, &response_data);
6360 EXPECT_THAT(rv, IsOk());
6361 EXPECT_EQ("Please Login\r\n", response_data);
6362
6363 EXPECT_TRUE(data1.AllReadDataConsumed());
6364 EXPECT_TRUE(data1.AllWriteDataConsumed());
6365 EXPECT_TRUE(data2.AllReadDataConsumed());
6366 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246367}
6368
[email protected]385a4672009-03-11 22:21:296369// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556370TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426371 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296372 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556373 request.url = GURL("https://server/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296374
Zentaro Kavanagh6ccee512017-09-28 18:34:096375 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6376 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276378
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376379 // Generate the NTLM messages based on known test data.
6380 std::string negotiate_msg;
6381 std::string challenge_msg;
6382 std::string authenticate_msg;
6383 base::Base64Encode(
6384 base::StringPiece(
6385 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6386 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6387 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556388 base::Base64Encode(
6389 base::StringPiece(
6390 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6391 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6392 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376393 base::Base64Encode(
6394 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096395 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556396 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6397 arraysize(
6398 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376399 &authenticate_msg);
6400
6401 // The authenticate message when |kWrongPassword| is sent.
6402 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556403 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6404 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6405 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6406 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6407 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6408 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376409
Zentaro Kavanagh1890a3d2018-01-29 19:52:556410 // Sanity check that it's the same length as the correct authenticate message
6411 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376412 ASSERT_EQ(authenticate_msg.length(),
6413 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556414 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376415
[email protected]385a4672009-03-11 22:21:296416 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556417 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6418 "Host: server\r\n"
6419 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296420 };
6421
6422 MockRead data_reads1[] = {
6423 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046424 // Negotiate and NTLM are often requested together. However, we only want
6425 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6426 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296427 MockRead("WWW-Authenticate: NTLM\r\n"),
6428 MockRead("Connection: close\r\n"),
6429 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366430 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296431 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296432 };
6433
6434 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166435 // After restarting with a null identity, this is the
6436 // request we should be issuing -- the final header line contains a Type
6437 // 1 message.
6438 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556439 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166440 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376441 "Authorization: NTLM "),
6442 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296443
bnc691fda62016-08-12 00:43:166444 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376445 // (using incorrect credentials). The second request continues on the
6446 // same connection.
bnc691fda62016-08-12 00:43:166447 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556448 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166449 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376450 "Authorization: NTLM "),
6451 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296452 };
6453
6454 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376455 // The origin server responds with a Type 2 message.
6456 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6457 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6458 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6459 MockRead("Content-Type: text/html\r\n\r\n"),
6460 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296461
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376462 // Wrong password.
6463 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6464 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6465 MockRead("Content-Length: 42\r\n"),
6466 MockRead("Content-Type: text/html\r\n\r\n"),
6467 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296468 };
6469
6470 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166471 // After restarting with a null identity, this is the
6472 // request we should be issuing -- the final header line contains a Type
6473 // 1 message.
6474 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556475 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166476 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376477 "Authorization: NTLM "),
6478 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296479
bnc691fda62016-08-12 00:43:166480 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6481 // (the credentials for the origin server). The second request continues
6482 // on the same connection.
6483 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556484 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166485 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376486 "Authorization: NTLM "),
6487 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296488 };
6489
6490 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026491 // The origin server responds with a Type 2 message.
6492 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376493 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6494 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026495 MockRead("Content-Type: text/html\r\n\r\n"),
6496 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296497
Bence Béky1e4ef192017-09-18 19:58:026498 // Lastly we get the desired content.
6499 MockRead("HTTP/1.1 200 OK\r\n"),
6500 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6501 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296502 };
6503
[email protected]31a2bfe2010-02-09 08:03:396504 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6505 data_writes1, arraysize(data_writes1));
6506 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6507 data_writes2, arraysize(data_writes2));
6508 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6509 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076510 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6511 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6512 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296513
Bence Béky83eb3512017-09-05 12:56:096514 SSLSocketDataProvider ssl1(ASYNC, OK);
6515 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6516 SSLSocketDataProvider ssl2(ASYNC, OK);
6517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6518 SSLSocketDataProvider ssl3(ASYNC, OK);
6519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6520
[email protected]49639fa2011-12-20 23:22:416521 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296522
bnc691fda62016-08-12 00:43:166523 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506524
tfarina42834112016-09-22 13:38:206525 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016526 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296527
6528 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016529 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296530
bnc691fda62016-08-12 00:43:166531 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296532
bnc691fda62016-08-12 00:43:166533 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526534 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046535 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296536
[email protected]49639fa2011-12-20 23:22:416537 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296538
[email protected]0757e7702009-03-27 04:00:226539 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376540 rv = trans.RestartWithAuth(
6541 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6542 callback2.callback());
robpercival214763f2016-07-01 23:27:016543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296544
[email protected]10af5fe72011-01-31 16:17:256545 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016546 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296547
bnc691fda62016-08-12 00:43:166548 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416549 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166550 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016551 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256552 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016553 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166554 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226555
bnc691fda62016-08-12 00:43:166556 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526557 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046558 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226559
[email protected]49639fa2011-12-20 23:22:416560 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226561
6562 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376563 rv = trans.RestartWithAuth(
6564 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6565 callback4.callback());
robpercival214763f2016-07-01 23:27:016566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256567
6568 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016569 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256570
bnc691fda62016-08-12 00:43:166571 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256572
[email protected]49639fa2011-12-20 23:22:416573 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256574
6575 // One more roundtrip
bnc691fda62016-08-12 00:43:166576 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226578
6579 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016580 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226581
bnc691fda62016-08-12 00:43:166582 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526583 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026584 EXPECT_EQ(14, response->headers->GetContentLength());
6585
6586 std::string response_data;
6587 rv = ReadTransaction(&trans, &response_data);
6588 EXPECT_THAT(rv, IsOk());
6589 EXPECT_EQ("Please Login\r\n", response_data);
6590
6591 EXPECT_TRUE(data1.AllReadDataConsumed());
6592 EXPECT_TRUE(data1.AllWriteDataConsumed());
6593 EXPECT_TRUE(data2.AllReadDataConsumed());
6594 EXPECT_TRUE(data2.AllWriteDataConsumed());
6595 EXPECT_TRUE(data3.AllReadDataConsumed());
6596 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296597}
Bence Béky83eb3512017-09-05 12:56:096598
Bence Béky3238f2e12017-09-22 22:44:496599// Server requests NTLM authentication, which is not supported over HTTP/2.
6600// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096601TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096602 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6603 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096604
Zentaro Kavanagh1890a3d2018-01-29 19:52:556605 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096606
6607 HttpRequestInfo request;
6608 request.method = "GET";
6609 request.url = GURL(kUrl);
6610
6611 // First request without credentials.
6612 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6613 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6614 1, std::move(request_headers0), LOWEST, true));
6615
6616 SpdyHeaderBlock response_headers0;
Bence Békybda82952017-10-02 17:35:276617 response_headers0[kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096618 response_headers0["www-authenticate"] = "NTLM";
6619 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6620 1, std::move(response_headers0), true));
6621
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376622 // Stream 1 is closed.
6623 spdy_util_.UpdateWithStreamDestruction(1);
6624
6625 // Generate the NTLM messages based on known test data.
6626 std::string negotiate_msg;
6627 std::string challenge_msg;
6628 std::string authenticate_msg;
6629 base::Base64Encode(
6630 base::StringPiece(
6631 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6632 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6633 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556634 base::Base64Encode(
6635 base::StringPiece(
6636 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6637 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6638 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376639 base::Base64Encode(
6640 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096641 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556642 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6643 arraysize(
6644 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376645 &authenticate_msg);
6646
6647 // Retry with authorization header.
6648 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6649 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
6650 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6651 3, std::move(request_headers1), LOWEST, true));
6652
6653 SpdySerializedFrame rst(
6654 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_HTTP_1_1_REQUIRED));
6655
Bence Béky3238f2e12017-09-22 22:44:496656 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6657 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096658
6659 // Retry yet again using HTTP/1.1.
6660 MockWrite writes1[] = {
6661 // After restarting with a null identity, this is the
6662 // request we should be issuing -- the final header line contains a Type
6663 // 1 message.
6664 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556665 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096666 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376667 "Authorization: NTLM "),
6668 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096669
6670 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6671 // (the credentials for the origin server). The second request continues
6672 // on the same connection.
6673 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556674 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096675 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376676 "Authorization: NTLM "),
6677 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096678 };
6679
6680 MockRead reads1[] = {
6681 // The origin server responds with a Type 2 message.
6682 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376683 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6684 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096685 MockRead("Content-Type: text/html\r\n\r\n"),
6686 MockRead("You are not authorized to view this page\r\n"),
6687
6688 // Lastly we get the desired content.
6689 MockRead("HTTP/1.1 200 OK\r\n"),
6690 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026691 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096692 };
6693 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6694 arraysize(writes0));
6695 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6696 arraysize(writes1));
6697 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6698 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6699
6700 SSLSocketDataProvider ssl0(ASYNC, OK);
6701 ssl0.next_proto = kProtoHTTP2;
6702 SSLSocketDataProvider ssl1(ASYNC, OK);
6703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6704 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6705
6706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6708
6709 TestCompletionCallback callback1;
6710 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6712
6713 rv = callback1.WaitForResult();
6714 EXPECT_THAT(rv, IsOk());
6715
6716 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6717
6718 const HttpResponseInfo* response = trans.GetResponseInfo();
6719 ASSERT_TRUE(response);
6720 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6721
6722 TestCompletionCallback callback2;
6723
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376724 rv = trans.RestartWithAuth(
6725 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6726 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6728
6729 rv = callback2.WaitForResult();
6730 EXPECT_THAT(rv, IsOk());
6731
6732 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6733
6734 response = trans.GetResponseInfo();
6735 ASSERT_TRUE(response);
6736 EXPECT_FALSE(response->auth_challenge);
6737
6738 TestCompletionCallback callback3;
6739
6740 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6742
6743 rv = callback3.WaitForResult();
6744 EXPECT_THAT(rv, IsOk());
6745
6746 response = trans.GetResponseInfo();
6747 ASSERT_TRUE(response);
6748 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026749 EXPECT_EQ(14, response->headers->GetContentLength());
6750
6751 std::string response_data;
6752 rv = ReadTransaction(&trans, &response_data);
6753 EXPECT_THAT(rv, IsOk());
6754 EXPECT_EQ("Please Login\r\n", response_data);
6755
6756 EXPECT_TRUE(data0.AllReadDataConsumed());
6757 EXPECT_TRUE(data0.AllWriteDataConsumed());
6758 EXPECT_TRUE(data1.AllReadDataConsumed());
6759 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096760}
[email protected]ea9dc9a2009-09-05 00:43:326761#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296762
[email protected]4ddaf2502008-10-23 18:26:196763// Test reading a server response which has only headers, and no body.
6764// After some maximum number of bytes is consumed, the transaction should
6765// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016766TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426767 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196768 request.method = "GET";
bncce36dca22015-04-21 22:11:236769 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196770
danakj1fd259a02016-04-16 03:17:096771 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166772 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276773
[email protected]b75b7b2f2009-10-06 00:54:536774 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436775 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536776 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196777
6778 MockRead data_reads[] = {
6779 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066780 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196781 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066782 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196783 };
[email protected]31a2bfe2010-02-09 08:03:396784 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076785 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196786
[email protected]49639fa2011-12-20 23:22:416787 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196788
tfarina42834112016-09-22 13:38:206789 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196791
6792 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016793 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196794}
[email protected]f4e426b2008-11-05 00:24:496795
6796// Make sure that we don't try to reuse a TCPClientSocket when failing to
6797// establish tunnel.
6798// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016799TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276800 HttpRequestInfo request;
6801 request.method = "GET";
bncce36dca22015-04-21 22:11:236802 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276803
[email protected]f4e426b2008-11-05 00:24:496804 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:596805 session_deps_.proxy_resolution_service =
6806 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016807
danakj1fd259a02016-04-16 03:17:096808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496809
bnc87dcefc2017-05-25 12:47:586810 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196811 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496812
[email protected]f4e426b2008-11-05 00:24:496813 // Since we have proxy, should try to establish tunnel.
6814 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176815 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6816 "Host: www.example.org:443\r\n"
6817 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496818 };
6819
[email protected]77848d12008-11-14 00:00:226820 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496821 // connection. Usually a proxy would return 501 (not implemented),
6822 // or 200 (tunnel established).
6823 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236824 MockRead("HTTP/1.1 404 Not Found\r\n"),
6825 MockRead("Content-Length: 10\r\n\r\n"),
6826 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496827 };
6828
[email protected]31a2bfe2010-02-09 08:03:396829 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6830 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076831 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496832
[email protected]49639fa2011-12-20 23:22:416833 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496834
tfarina42834112016-09-22 13:38:206835 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496837
6838 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016839 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496840
[email protected]b4404c02009-04-10 16:38:526841 // Empty the current queue. This is necessary because idle sockets are
6842 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556843 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526844
[email protected]f4e426b2008-11-05 00:24:496845 // We now check to make sure the TCPClientSocket was not added back to
6846 // the pool.
[email protected]90499482013-06-01 00:39:506847 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496848 trans.reset();
fdoray92e35a72016-06-10 15:54:556849 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496850 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506851 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496852}
[email protected]372d34a2008-11-05 21:30:516853
[email protected]1b157c02009-04-21 01:55:406854// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016855TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426856 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406857 request.method = "GET";
bncce36dca22015-04-21 22:11:236858 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406859
danakj1fd259a02016-04-16 03:17:096860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276861
bnc691fda62016-08-12 00:43:166862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276863
[email protected]1b157c02009-04-21 01:55:406864 MockRead data_reads[] = {
6865 // A part of the response body is received with the response headers.
6866 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6867 // The rest of the response body is received in two parts.
6868 MockRead("lo"),
6869 MockRead(" world"),
6870 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066871 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406872 };
6873
[email protected]31a2bfe2010-02-09 08:03:396874 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076875 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406876
[email protected]49639fa2011-12-20 23:22:416877 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406878
tfarina42834112016-09-22 13:38:206879 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406881
6882 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016883 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406884
bnc691fda62016-08-12 00:43:166885 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526886 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406887
wezca1070932016-05-26 20:30:526888 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406889 std::string status_line = response->headers->GetStatusLine();
6890 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6891
[email protected]90499482013-06-01 00:39:506892 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406893
6894 std::string response_data;
bnc691fda62016-08-12 00:43:166895 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016896 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406897 EXPECT_EQ("hello world", response_data);
6898
6899 // Empty the current queue. This is necessary because idle sockets are
6900 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556901 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406902
6903 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506904 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406905}
6906
[email protected]76a505b2010-08-25 06:23:006907// Make sure that we recycle a SSL socket after reading all of the response
6908// body.
bncd16676a2016-07-20 16:23:016909TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006910 HttpRequestInfo request;
6911 request.method = "GET";
bncce36dca22015-04-21 22:11:236912 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006913
6914 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236915 MockWrite(
6916 "GET / HTTP/1.1\r\n"
6917 "Host: www.example.org\r\n"
6918 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006919 };
6920
6921 MockRead data_reads[] = {
6922 MockRead("HTTP/1.1 200 OK\r\n"),
6923 MockRead("Content-Length: 11\r\n\r\n"),
6924 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066925 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006926 };
6927
[email protected]8ddf8322012-02-23 18:08:066928 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006930
6931 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6932 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076933 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006934
[email protected]49639fa2011-12-20 23:22:416935 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006936
danakj1fd259a02016-04-16 03:17:096937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006939
tfarina42834112016-09-22 13:38:206940 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006941
robpercival214763f2016-07-01 23:27:016942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6943 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006944
bnc691fda62016-08-12 00:43:166945 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526946 ASSERT_TRUE(response);
6947 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006948 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6949
[email protected]90499482013-06-01 00:39:506950 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006951
6952 std::string response_data;
bnc691fda62016-08-12 00:43:166953 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016954 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006955 EXPECT_EQ("hello world", response_data);
6956
6957 // Empty the current queue. This is necessary because idle sockets are
6958 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556959 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006960
6961 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506962 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006963}
6964
6965// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6966// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016967TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006968 HttpRequestInfo request;
6969 request.method = "GET";
bncce36dca22015-04-21 22:11:236970 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006971
6972 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236973 MockWrite(
6974 "GET / HTTP/1.1\r\n"
6975 "Host: www.example.org\r\n"
6976 "Connection: keep-alive\r\n\r\n"),
6977 MockWrite(
6978 "GET / HTTP/1.1\r\n"
6979 "Host: www.example.org\r\n"
6980 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006981 };
6982
6983 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426984 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6985 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006986
[email protected]8ddf8322012-02-23 18:08:066987 SSLSocketDataProvider ssl(ASYNC, OK);
6988 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076989 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006991
6992 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6993 data_writes, arraysize(data_writes));
6994 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6995 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076996 session_deps_.socket_factory->AddSocketDataProvider(&data);
6997 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006998
[email protected]49639fa2011-12-20 23:22:416999 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007000
danakj1fd259a02016-04-16 03:17:097001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587002 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197003 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007004
tfarina42834112016-09-22 13:38:207005 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007006
robpercival214763f2016-07-01 23:27:017007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7008 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007009
7010 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527011 ASSERT_TRUE(response);
7012 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007013 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7014
[email protected]90499482013-06-01 00:39:507015 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007016
7017 std::string response_data;
7018 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017019 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007020 EXPECT_EQ("hello world", response_data);
7021
7022 // Empty the current queue. This is necessary because idle sockets are
7023 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557024 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007025
7026 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507027 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007028
7029 // Now start the second transaction, which should reuse the previous socket.
7030
bnc87dcefc2017-05-25 12:47:587031 trans =
Jeremy Roman0579ed62017-08-29 15:56:197032 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007033
tfarina42834112016-09-22 13:38:207034 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007035
robpercival214763f2016-07-01 23:27:017036 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7037 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007038
7039 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527040 ASSERT_TRUE(response);
7041 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007042 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7043
[email protected]90499482013-06-01 00:39:507044 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007045
7046 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017047 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007048 EXPECT_EQ("hello world", response_data);
7049
7050 // Empty the current queue. This is necessary because idle sockets are
7051 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557052 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007053
7054 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507055 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007056}
7057
maksim.sisov0adf8592016-07-15 06:25:567058// Grab a socket, use it, and put it back into the pool. Then, make
7059// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017060TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567061 HttpRequestInfo request;
7062 request.method = "GET";
7063 request.url = GURL("http://www.example.org/");
7064 request.load_flags = 0;
7065
7066 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7067
bnc691fda62016-08-12 00:43:167068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567069
7070 MockRead data_reads[] = {
7071 // A part of the response body is received with the response headers.
7072 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7073 // The rest of the response body is received in two parts.
7074 MockRead("lo"), MockRead(" world"),
7075 MockRead("junk"), // Should not be read!!
7076 MockRead(SYNCHRONOUS, OK),
7077 };
7078
7079 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7080 session_deps_.socket_factory->AddSocketDataProvider(&data);
7081
7082 TestCompletionCallback callback;
7083
tfarina42834112016-09-22 13:38:207084 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7086
7087 EXPECT_THAT(callback.GetResult(rv), IsOk());
7088
bnc691fda62016-08-12 00:43:167089 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567090 ASSERT_TRUE(response);
7091 EXPECT_TRUE(response->headers);
7092 std::string status_line = response->headers->GetStatusLine();
7093 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7094
7095 // Make memory critical notification and ensure the transaction still has been
7096 // operating right.
7097 base::MemoryPressureListener::NotifyMemoryPressure(
7098 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7099 base::RunLoop().RunUntilIdle();
7100
7101 // Socket should not be flushed as long as it is not idle.
7102 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7103
7104 std::string response_data;
bnc691fda62016-08-12 00:43:167105 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567106 EXPECT_THAT(rv, IsOk());
7107 EXPECT_EQ("hello world", response_data);
7108
7109 // Empty the current queue. This is necessary because idle sockets are
7110 // added to the connection pool asynchronously with a PostTask.
7111 base::RunLoop().RunUntilIdle();
7112
7113 // We now check to make sure the socket was added back to the pool.
7114 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7115
7116 // Idle sockets should be flushed now.
7117 base::MemoryPressureListener::NotifyMemoryPressure(
7118 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7119 base::RunLoop().RunUntilIdle();
7120
7121 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7122}
7123
yucliu48f235d2018-01-11 00:59:557124// Disable idle socket closing on memory pressure.
7125// Grab a socket, use it, and put it back into the pool. Then, make
7126// low memory notification and ensure the socket pool is NOT flushed.
7127TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7128 HttpRequestInfo request;
7129 request.method = "GET";
7130 request.url = GURL("http://www.example.org/");
7131 request.load_flags = 0;
7132
7133 // Disable idle socket closing on memory pressure.
7134 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7136
7137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7138
7139 MockRead data_reads[] = {
7140 // A part of the response body is received with the response headers.
7141 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7142 // The rest of the response body is received in two parts.
7143 MockRead("lo"), MockRead(" world"),
7144 MockRead("junk"), // Should not be read!!
7145 MockRead(SYNCHRONOUS, OK),
7146 };
7147
7148 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7149 session_deps_.socket_factory->AddSocketDataProvider(&data);
7150
7151 TestCompletionCallback callback;
7152
7153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7155
7156 EXPECT_THAT(callback.GetResult(rv), IsOk());
7157
7158 const HttpResponseInfo* response = trans.GetResponseInfo();
7159 ASSERT_TRUE(response);
7160 EXPECT_TRUE(response->headers);
7161 std::string status_line = response->headers->GetStatusLine();
7162 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7163
7164 // Make memory critical notification and ensure the transaction still has been
7165 // operating right.
7166 base::MemoryPressureListener::NotifyMemoryPressure(
7167 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7168 base::RunLoop().RunUntilIdle();
7169
7170 // Socket should not be flushed as long as it is not idle.
7171 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7172
7173 std::string response_data;
7174 rv = ReadTransaction(&trans, &response_data);
7175 EXPECT_THAT(rv, IsOk());
7176 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.
7180 base::RunLoop().RunUntilIdle();
7181
7182 // We now check to make sure the socket was added back to the pool.
7183 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7184
7185 // Idle sockets should NOT be flushed on moderate memory pressure.
7186 base::MemoryPressureListener::NotifyMemoryPressure(
7187 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7188 base::RunLoop().RunUntilIdle();
7189
7190 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7191
7192 // Idle sockets should NOT be flushed on critical memory pressure.
7193 base::MemoryPressureListener::NotifyMemoryPressure(
7194 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7195 base::RunLoop().RunUntilIdle();
7196
7197 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7198}
7199
maksim.sisov0adf8592016-07-15 06:25:567200// Grab an SSL socket, use it, and put it back into the pool. Then, make
7201// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017202TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567203 HttpRequestInfo request;
7204 request.method = "GET";
7205 request.url = GURL("https://www.example.org/");
7206 request.load_flags = 0;
7207
7208 MockWrite data_writes[] = {
7209 MockWrite("GET / HTTP/1.1\r\n"
7210 "Host: www.example.org\r\n"
7211 "Connection: keep-alive\r\n\r\n"),
7212 };
7213
7214 MockRead data_reads[] = {
7215 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7216 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7217
7218 SSLSocketDataProvider ssl(ASYNC, OK);
7219 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7220
7221 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7222 arraysize(data_writes));
7223 session_deps_.socket_factory->AddSocketDataProvider(&data);
7224
7225 TestCompletionCallback callback;
7226
7227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567229
7230 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207231 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567232
7233 EXPECT_THAT(callback.GetResult(rv), IsOk());
7234
bnc691fda62016-08-12 00:43:167235 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567236 ASSERT_TRUE(response);
7237 ASSERT_TRUE(response->headers);
7238 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7239
7240 // Make memory critical notification and ensure the transaction still has been
7241 // operating right.
7242 base::MemoryPressureListener::NotifyMemoryPressure(
7243 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7244 base::RunLoop().RunUntilIdle();
7245
7246 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7247
7248 std::string response_data;
bnc691fda62016-08-12 00:43:167249 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567250 EXPECT_THAT(rv, IsOk());
7251 EXPECT_EQ("hello world", response_data);
7252
7253 // Empty the current queue. This is necessary because idle sockets are
7254 // added to the connection pool asynchronously with a PostTask.
7255 base::RunLoop().RunUntilIdle();
7256
7257 // We now check to make sure the socket was added back to the pool.
7258 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7259
7260 // Make memory notification once again and ensure idle socket is closed.
7261 base::MemoryPressureListener::NotifyMemoryPressure(
7262 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7263 base::RunLoop().RunUntilIdle();
7264
7265 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7266}
7267
[email protected]b4404c02009-04-10 16:38:527268// Make sure that we recycle a socket after a zero-length response.
7269// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017270TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427271 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527272 request.method = "GET";
bncce36dca22015-04-21 22:11:237273 request.url = GURL(
7274 "http://www.example.org/csi?v=3&s=web&action=&"
7275 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7276 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7277 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:527278
danakj1fd259a02016-04-16 03:17:097279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277280
[email protected]b4404c02009-04-10 16:38:527281 MockRead data_reads[] = {
7282 MockRead("HTTP/1.1 204 No Content\r\n"
7283 "Content-Length: 0\r\n"
7284 "Content-Type: text/html\r\n\r\n"),
7285 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067286 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527287 };
7288
[email protected]31a2bfe2010-02-09 08:03:397289 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077290 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527291
mmenkecc2298e2015-12-07 18:20:187292 // Transaction must be created after the MockReads, so it's destroyed before
7293 // them.
bnc691fda62016-08-12 00:43:167294 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187295
[email protected]49639fa2011-12-20 23:22:417296 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527297
tfarina42834112016-09-22 13:38:207298 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017299 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527300
7301 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017302 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527303
bnc691fda62016-08-12 00:43:167304 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527305 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527306
wezca1070932016-05-26 20:30:527307 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527308 std::string status_line = response->headers->GetStatusLine();
7309 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7310
[email protected]90499482013-06-01 00:39:507311 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527312
7313 std::string response_data;
bnc691fda62016-08-12 00:43:167314 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017315 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527316 EXPECT_EQ("", response_data);
7317
7318 // Empty the current queue. This is necessary because idle sockets are
7319 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557320 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527321
7322 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507323 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527324}
7325
bncd16676a2016-07-20 16:23:017326TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097327 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227328 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197329 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227330 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277331
[email protected]1c773ea12009-04-28 19:58:427332 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517333 // Transaction 1: a GET request that succeeds. The socket is recycled
7334 // after use.
7335 request[0].method = "GET";
7336 request[0].url = GURL("http://www.google.com/");
7337 request[0].load_flags = 0;
7338 // Transaction 2: a POST request. Reuses the socket kept alive from
7339 // transaction 1. The first attempts fails when writing the POST data.
7340 // This causes the transaction to retry with a new socket. The second
7341 // attempt succeeds.
7342 request[1].method = "POST";
7343 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277344 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517345 request[1].load_flags = 0;
7346
danakj1fd259a02016-04-16 03:17:097347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517348
7349 // The first socket is used for transaction 1 and the first attempt of
7350 // transaction 2.
7351
7352 // The response of transaction 1.
7353 MockRead data_reads1[] = {
7354 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7355 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067356 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517357 };
7358 // The mock write results of transaction 1 and the first attempt of
7359 // transaction 2.
7360 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067361 MockWrite(SYNCHRONOUS, 64), // GET
7362 MockWrite(SYNCHRONOUS, 93), // POST
7363 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517364 };
[email protected]31a2bfe2010-02-09 08:03:397365 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7366 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:517367
7368 // The second socket is used for the second attempt of transaction 2.
7369
7370 // The response of transaction 2.
7371 MockRead data_reads2[] = {
7372 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7373 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067374 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517375 };
7376 // The mock write results of the second attempt of transaction 2.
7377 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067378 MockWrite(SYNCHRONOUS, 93), // POST
7379 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517380 };
[email protected]31a2bfe2010-02-09 08:03:397381 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7382 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517383
[email protected]bb88e1d32013-05-03 23:11:077384 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7385 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517386
thestig9d3bb0c2015-01-24 00:49:517387 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517388 "hello world", "welcome"
7389 };
7390
7391 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517393
[email protected]49639fa2011-12-20 23:22:417394 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517395
tfarina42834112016-09-22 13:38:207396 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517398
7399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017400 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517401
bnc691fda62016-08-12 00:43:167402 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527403 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517404
wezca1070932016-05-26 20:30:527405 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517406 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7407
7408 std::string response_data;
bnc691fda62016-08-12 00:43:167409 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017410 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517411 EXPECT_EQ(kExpectedResponseData[i], response_data);
7412 }
7413}
[email protected]f9ee6b52008-11-08 06:46:237414
7415// Test the request-challenge-retry sequence for basic auth when there is
7416// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167417// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017418TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427419 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237420 request.method = "GET";
bncce36dca22015-04-21 22:11:237421 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417422 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:297423
danakj1fd259a02016-04-16 03:17:097424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167425 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277426
[email protected]a97cca42009-08-14 01:00:297427 // The password contains an escaped character -- for this test to pass it
7428 // will need to be unescaped by HttpNetworkTransaction.
7429 EXPECT_EQ("b%40r", request.url.password());
7430
[email protected]f9ee6b52008-11-08 06:46:237431 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237432 MockWrite(
7433 "GET / HTTP/1.1\r\n"
7434 "Host: www.example.org\r\n"
7435 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237436 };
7437
7438 MockRead data_reads1[] = {
7439 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7440 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7441 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067442 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237443 };
7444
[email protected]2262e3a2012-05-22 16:08:167445 // After the challenge above, the transaction will be restarted using the
7446 // identity from the url (foo, b@r) to answer the challenge.
7447 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237448 MockWrite(
7449 "GET / HTTP/1.1\r\n"
7450 "Host: www.example.org\r\n"
7451 "Connection: keep-alive\r\n"
7452 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167453 };
7454
7455 MockRead data_reads2[] = {
7456 MockRead("HTTP/1.0 200 OK\r\n"),
7457 MockRead("Content-Length: 100\r\n\r\n"),
7458 MockRead(SYNCHRONOUS, OK),
7459 };
7460
[email protected]31a2bfe2010-02-09 08:03:397461 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7462 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167463 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7464 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077465 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7466 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237467
[email protected]49639fa2011-12-20 23:22:417468 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207469 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237471 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017472 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167473 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167474
7475 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167476 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167478 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017479 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167480 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227481
bnc691fda62016-08-12 00:43:167482 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527483 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167484
7485 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527486 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167487
7488 EXPECT_EQ(100, response->headers->GetContentLength());
7489
7490 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557491 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167492}
7493
7494// Test the request-challenge-retry sequence for basic auth when there is an
7495// incorrect identity in the URL. The identity from the URL should be used only
7496// once.
bncd16676a2016-07-20 16:23:017497TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167498 HttpRequestInfo request;
7499 request.method = "GET";
7500 // Note: the URL has a username:password in it. The password "baz" is
7501 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237502 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167503
7504 request.load_flags = LOAD_NORMAL;
7505
danakj1fd259a02016-04-16 03:17:097506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167508
7509 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237510 MockWrite(
7511 "GET / HTTP/1.1\r\n"
7512 "Host: www.example.org\r\n"
7513 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167514 };
7515
7516 MockRead data_reads1[] = {
7517 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7518 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7519 MockRead("Content-Length: 10\r\n\r\n"),
7520 MockRead(SYNCHRONOUS, ERR_FAILED),
7521 };
7522
7523 // After the challenge above, the transaction will be restarted using the
7524 // identity from the url (foo, baz) to answer the challenge.
7525 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237526 MockWrite(
7527 "GET / HTTP/1.1\r\n"
7528 "Host: www.example.org\r\n"
7529 "Connection: keep-alive\r\n"
7530 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167531 };
7532
7533 MockRead data_reads2[] = {
7534 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7535 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7536 MockRead("Content-Length: 10\r\n\r\n"),
7537 MockRead(SYNCHRONOUS, ERR_FAILED),
7538 };
7539
7540 // After the challenge above, the transaction will be restarted using the
7541 // identity supplied by the user (foo, bar) to answer the challenge.
7542 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237543 MockWrite(
7544 "GET / HTTP/1.1\r\n"
7545 "Host: www.example.org\r\n"
7546 "Connection: keep-alive\r\n"
7547 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167548 };
7549
7550 MockRead data_reads3[] = {
7551 MockRead("HTTP/1.0 200 OK\r\n"),
7552 MockRead("Content-Length: 100\r\n\r\n"),
7553 MockRead(SYNCHRONOUS, OK),
7554 };
7555
7556 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7557 data_writes1, arraysize(data_writes1));
7558 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7559 data_writes2, arraysize(data_writes2));
7560 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7561 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077562 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7563 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7564 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167565
7566 TestCompletionCallback callback1;
7567
tfarina42834112016-09-22 13:38:207568 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017569 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167570
7571 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017572 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167573
bnc691fda62016-08-12 00:43:167574 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167575 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167576 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167578 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017579 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167580 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167581
bnc691fda62016-08-12 00:43:167582 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527583 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167584 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7585
7586 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167587 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017588 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167589 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017590 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167591 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167592
bnc691fda62016-08-12 00:43:167593 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527594 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167595
7596 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527597 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167598
7599 EXPECT_EQ(100, response->headers->GetContentLength());
7600
[email protected]ea9dc9a2009-09-05 00:43:327601 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557602 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327603}
7604
[email protected]2217aa22013-10-11 03:03:547605
7606// Test the request-challenge-retry sequence for basic auth when there is a
7607// correct identity in the URL, but its use is being suppressed. The identity
7608// from the URL should never be used.
bncd16676a2016-07-20 16:23:017609TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547610 HttpRequestInfo request;
7611 request.method = "GET";
bncce36dca22015-04-21 22:11:237612 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547613 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7614
danakj1fd259a02016-04-16 03:17:097615 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547617
7618 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237619 MockWrite(
7620 "GET / HTTP/1.1\r\n"
7621 "Host: www.example.org\r\n"
7622 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547623 };
7624
7625 MockRead data_reads1[] = {
7626 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7627 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7628 MockRead("Content-Length: 10\r\n\r\n"),
7629 MockRead(SYNCHRONOUS, ERR_FAILED),
7630 };
7631
7632 // After the challenge above, the transaction will be restarted using the
7633 // identity supplied by the user, not the one in the URL, to answer the
7634 // challenge.
7635 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237636 MockWrite(
7637 "GET / HTTP/1.1\r\n"
7638 "Host: www.example.org\r\n"
7639 "Connection: keep-alive\r\n"
7640 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547641 };
7642
7643 MockRead data_reads3[] = {
7644 MockRead("HTTP/1.0 200 OK\r\n"),
7645 MockRead("Content-Length: 100\r\n\r\n"),
7646 MockRead(SYNCHRONOUS, OK),
7647 };
7648
7649 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7650 data_writes1, arraysize(data_writes1));
7651 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7652 data_writes3, arraysize(data_writes3));
7653 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7654 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7655
7656 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207657 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017658 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547659 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017660 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167661 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547662
bnc691fda62016-08-12 00:43:167663 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527664 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547665 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7666
7667 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167668 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547670 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017671 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167672 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547673
bnc691fda62016-08-12 00:43:167674 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527675 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547676
7677 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527678 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547679 EXPECT_EQ(100, response->headers->GetContentLength());
7680
7681 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557682 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547683}
7684
[email protected]f9ee6b52008-11-08 06:46:237685// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017686TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237688
7689 // Transaction 1: authenticate (foo, bar) on MyRealm1
7690 {
[email protected]1c773ea12009-04-28 19:58:427691 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237692 request.method = "GET";
bncce36dca22015-04-21 22:11:237693 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237694
bnc691fda62016-08-12 00:43:167695 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277696
[email protected]f9ee6b52008-11-08 06:46:237697 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237698 MockWrite(
7699 "GET /x/y/z HTTP/1.1\r\n"
7700 "Host: www.example.org\r\n"
7701 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237702 };
7703
7704 MockRead data_reads1[] = {
7705 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7706 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7707 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067708 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237709 };
7710
7711 // Resend with authorization (username=foo, password=bar)
7712 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237713 MockWrite(
7714 "GET /x/y/z HTTP/1.1\r\n"
7715 "Host: www.example.org\r\n"
7716 "Connection: keep-alive\r\n"
7717 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237718 };
7719
7720 // Sever accepts the authorization.
7721 MockRead data_reads2[] = {
7722 MockRead("HTTP/1.0 200 OK\r\n"),
7723 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067724 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237725 };
7726
[email protected]31a2bfe2010-02-09 08:03:397727 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7728 data_writes1, arraysize(data_writes1));
7729 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7730 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077731 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7732 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237733
[email protected]49639fa2011-12-20 23:22:417734 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237735
tfarina42834112016-09-22 13:38:207736 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017737 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237738
7739 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017740 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237741
bnc691fda62016-08-12 00:43:167742 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527743 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047744 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237745
[email protected]49639fa2011-12-20 23:22:417746 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237747
bnc691fda62016-08-12 00:43:167748 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7749 callback2.callback());
robpercival214763f2016-07-01 23:27:017750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237751
7752 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017753 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237754
bnc691fda62016-08-12 00:43:167755 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527756 ASSERT_TRUE(response);
7757 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237758 EXPECT_EQ(100, response->headers->GetContentLength());
7759 }
7760
7761 // ------------------------------------------------------------------------
7762
7763 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7764 {
[email protected]1c773ea12009-04-28 19:58:427765 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237766 request.method = "GET";
7767 // Note that Transaction 1 was at /x/y/z, so this is in the same
7768 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237769 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237770
bnc691fda62016-08-12 00:43:167771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277772
[email protected]f9ee6b52008-11-08 06:46:237773 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237774 MockWrite(
7775 "GET /x/y/a/b HTTP/1.1\r\n"
7776 "Host: www.example.org\r\n"
7777 "Connection: keep-alive\r\n"
7778 // Send preemptive authorization for MyRealm1
7779 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237780 };
7781
7782 // The server didn't like the preemptive authorization, and
7783 // challenges us for a different realm (MyRealm2).
7784 MockRead data_reads1[] = {
7785 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7786 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7787 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067788 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237789 };
7790
7791 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7792 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237793 MockWrite(
7794 "GET /x/y/a/b HTTP/1.1\r\n"
7795 "Host: www.example.org\r\n"
7796 "Connection: keep-alive\r\n"
7797 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237798 };
7799
7800 // Sever accepts the authorization.
7801 MockRead data_reads2[] = {
7802 MockRead("HTTP/1.0 200 OK\r\n"),
7803 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067804 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237805 };
7806
[email protected]31a2bfe2010-02-09 08:03:397807 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7808 data_writes1, arraysize(data_writes1));
7809 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7810 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077811 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7812 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237813
[email protected]49639fa2011-12-20 23:22:417814 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237815
tfarina42834112016-09-22 13:38:207816 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237818
7819 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017820 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237821
bnc691fda62016-08-12 00:43:167822 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527823 ASSERT_TRUE(response);
7824 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047825 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437826 EXPECT_EQ("http://www.example.org",
7827 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047828 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197829 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237830
[email protected]49639fa2011-12-20 23:22:417831 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237832
bnc691fda62016-08-12 00:43:167833 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7834 callback2.callback());
robpercival214763f2016-07-01 23:27:017835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237836
7837 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017838 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237839
bnc691fda62016-08-12 00:43:167840 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527841 ASSERT_TRUE(response);
7842 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237843 EXPECT_EQ(100, response->headers->GetContentLength());
7844 }
7845
7846 // ------------------------------------------------------------------------
7847
7848 // Transaction 3: Resend a request in MyRealm's protection space --
7849 // succeed with preemptive authorization.
7850 {
[email protected]1c773ea12009-04-28 19:58:427851 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237852 request.method = "GET";
bncce36dca22015-04-21 22:11:237853 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237854
bnc691fda62016-08-12 00:43:167855 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277856
[email protected]f9ee6b52008-11-08 06:46:237857 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237858 MockWrite(
7859 "GET /x/y/z2 HTTP/1.1\r\n"
7860 "Host: www.example.org\r\n"
7861 "Connection: keep-alive\r\n"
7862 // The authorization for MyRealm1 gets sent preemptively
7863 // (since the url is in the same protection space)
7864 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237865 };
7866
7867 // Sever accepts the preemptive authorization
7868 MockRead data_reads1[] = {
7869 MockRead("HTTP/1.0 200 OK\r\n"),
7870 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067871 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237872 };
7873
[email protected]31a2bfe2010-02-09 08:03:397874 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7875 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237877
[email protected]49639fa2011-12-20 23:22:417878 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237879
tfarina42834112016-09-22 13:38:207880 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237882
7883 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017884 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237885
bnc691fda62016-08-12 00:43:167886 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527887 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237888
wezca1070932016-05-26 20:30:527889 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237890 EXPECT_EQ(100, response->headers->GetContentLength());
7891 }
7892
7893 // ------------------------------------------------------------------------
7894
7895 // Transaction 4: request another URL in MyRealm (however the
7896 // url is not known to belong to the protection space, so no pre-auth).
7897 {
[email protected]1c773ea12009-04-28 19:58:427898 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237899 request.method = "GET";
bncce36dca22015-04-21 22:11:237900 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237901
bnc691fda62016-08-12 00:43:167902 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277903
[email protected]f9ee6b52008-11-08 06:46:237904 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237905 MockWrite(
7906 "GET /x/1 HTTP/1.1\r\n"
7907 "Host: www.example.org\r\n"
7908 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237909 };
7910
7911 MockRead data_reads1[] = {
7912 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7913 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7914 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067915 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237916 };
7917
7918 // Resend with authorization from MyRealm's cache.
7919 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237920 MockWrite(
7921 "GET /x/1 HTTP/1.1\r\n"
7922 "Host: www.example.org\r\n"
7923 "Connection: keep-alive\r\n"
7924 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237925 };
7926
7927 // Sever accepts the authorization.
7928 MockRead data_reads2[] = {
7929 MockRead("HTTP/1.0 200 OK\r\n"),
7930 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067931 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237932 };
7933
[email protected]31a2bfe2010-02-09 08:03:397934 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7935 data_writes1, arraysize(data_writes1));
7936 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7937 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077938 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7939 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237940
[email protected]49639fa2011-12-20 23:22:417941 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237942
tfarina42834112016-09-22 13:38:207943 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237945
7946 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017947 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237948
bnc691fda62016-08-12 00:43:167949 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417950 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167951 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017952 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227953 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017954 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167955 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227956
bnc691fda62016-08-12 00:43:167957 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527958 ASSERT_TRUE(response);
7959 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237960 EXPECT_EQ(100, response->headers->GetContentLength());
7961 }
7962
7963 // ------------------------------------------------------------------------
7964
7965 // Transaction 5: request a URL in MyRealm, but the server rejects the
7966 // cached identity. Should invalidate and re-prompt.
7967 {
[email protected]1c773ea12009-04-28 19:58:427968 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237969 request.method = "GET";
bncce36dca22015-04-21 22:11:237970 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237971
bnc691fda62016-08-12 00:43:167972 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277973
[email protected]f9ee6b52008-11-08 06:46:237974 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237975 MockWrite(
7976 "GET /p/q/t HTTP/1.1\r\n"
7977 "Host: www.example.org\r\n"
7978 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237979 };
7980
7981 MockRead data_reads1[] = {
7982 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7983 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7984 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067985 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237986 };
7987
7988 // Resend with authorization from cache for MyRealm.
7989 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237990 MockWrite(
7991 "GET /p/q/t HTTP/1.1\r\n"
7992 "Host: www.example.org\r\n"
7993 "Connection: keep-alive\r\n"
7994 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237995 };
7996
7997 // Sever rejects the authorization.
7998 MockRead data_reads2[] = {
7999 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8000 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8001 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068002 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238003 };
8004
8005 // At this point we should prompt for new credentials for MyRealm.
8006 // Restart with username=foo3, password=foo4.
8007 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238008 MockWrite(
8009 "GET /p/q/t HTTP/1.1\r\n"
8010 "Host: www.example.org\r\n"
8011 "Connection: keep-alive\r\n"
8012 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238013 };
8014
8015 // Sever accepts the authorization.
8016 MockRead data_reads3[] = {
8017 MockRead("HTTP/1.0 200 OK\r\n"),
8018 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068019 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238020 };
8021
[email protected]31a2bfe2010-02-09 08:03:398022 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8023 data_writes1, arraysize(data_writes1));
8024 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8025 data_writes2, arraysize(data_writes2));
8026 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8027 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:078028 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8029 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8030 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238031
[email protected]49639fa2011-12-20 23:22:418032 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238033
tfarina42834112016-09-22 13:38:208034 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238036
8037 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018038 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238039
bnc691fda62016-08-12 00:43:168040 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418041 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168042 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228044 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018045 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168046 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228047
bnc691fda62016-08-12 00:43:168048 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528049 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048050 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238051
[email protected]49639fa2011-12-20 23:22:418052 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238053
bnc691fda62016-08-12 00:43:168054 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8055 callback3.callback());
robpercival214763f2016-07-01 23:27:018056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238057
[email protected]0757e7702009-03-27 04:00:228058 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018059 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238060
bnc691fda62016-08-12 00:43:168061 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528062 ASSERT_TRUE(response);
8063 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238064 EXPECT_EQ(100, response->headers->GetContentLength());
8065 }
8066}
[email protected]89ceba9a2009-03-21 03:46:068067
[email protected]3c32c5f2010-05-18 15:18:128068// Tests that nonce count increments when multiple auth attempts
8069// are started with the same nonce.
bncd16676a2016-07-20 16:23:018070TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448071 HttpAuthHandlerDigest::Factory* digest_factory =
8072 new HttpAuthHandlerDigest::Factory();
8073 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8074 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8075 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078076 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128078
8079 // Transaction 1: authenticate (foo, bar) on MyRealm1
8080 {
[email protected]3c32c5f2010-05-18 15:18:128081 HttpRequestInfo request;
8082 request.method = "GET";
bncce36dca22015-04-21 22:11:238083 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:128084
bnc691fda62016-08-12 00:43:168085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278086
[email protected]3c32c5f2010-05-18 15:18:128087 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238088 MockWrite(
8089 "GET /x/y/z HTTP/1.1\r\n"
8090 "Host: www.example.org\r\n"
8091 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128092 };
8093
8094 MockRead data_reads1[] = {
8095 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8096 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8097 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068098 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128099 };
8100
8101 // Resend with authorization (username=foo, password=bar)
8102 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238103 MockWrite(
8104 "GET /x/y/z HTTP/1.1\r\n"
8105 "Host: www.example.org\r\n"
8106 "Connection: keep-alive\r\n"
8107 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8108 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8109 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8110 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128111 };
8112
8113 // Sever accepts the authorization.
8114 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088115 MockRead("HTTP/1.0 200 OK\r\n"),
8116 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128117 };
8118
8119 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8120 data_writes1, arraysize(data_writes1));
8121 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8122 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128125
[email protected]49639fa2011-12-20 23:22:418126 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128127
tfarina42834112016-09-22 13:38:208128 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128130
8131 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018132 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128133
bnc691fda62016-08-12 00:43:168134 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528135 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048136 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128137
[email protected]49639fa2011-12-20 23:22:418138 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128139
bnc691fda62016-08-12 00:43:168140 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8141 callback2.callback());
robpercival214763f2016-07-01 23:27:018142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128143
8144 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018145 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128146
bnc691fda62016-08-12 00:43:168147 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528148 ASSERT_TRUE(response);
8149 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128150 }
8151
8152 // ------------------------------------------------------------------------
8153
8154 // Transaction 2: Request another resource in digestive's protection space.
8155 // This will preemptively add an Authorization header which should have an
8156 // "nc" value of 2 (as compared to 1 in the first use.
8157 {
[email protected]3c32c5f2010-05-18 15:18:128158 HttpRequestInfo request;
8159 request.method = "GET";
8160 // Note that Transaction 1 was at /x/y/z, so this is in the same
8161 // protection space as digest.
bncce36dca22015-04-21 22:11:238162 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:128163
bnc691fda62016-08-12 00:43:168164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278165
[email protected]3c32c5f2010-05-18 15:18:128166 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238167 MockWrite(
8168 "GET /x/y/a/b HTTP/1.1\r\n"
8169 "Host: www.example.org\r\n"
8170 "Connection: keep-alive\r\n"
8171 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8172 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8173 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8174 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128175 };
8176
8177 // Sever accepts the authorization.
8178 MockRead data_reads1[] = {
8179 MockRead("HTTP/1.0 200 OK\r\n"),
8180 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068181 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128182 };
8183
8184 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8185 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078186 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128187
[email protected]49639fa2011-12-20 23:22:418188 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128189
tfarina42834112016-09-22 13:38:208190 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018191 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128192
8193 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018194 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128195
bnc691fda62016-08-12 00:43:168196 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528197 ASSERT_TRUE(response);
8198 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128199 }
8200}
8201
[email protected]89ceba9a2009-03-21 03:46:068202// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018203TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068204 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168206 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068207
8208 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168209 trans.read_buf_ = new IOBuffer(15);
8210 trans.read_buf_len_ = 15;
8211 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068212
8213 // Setup state in response_
bnc691fda62016-08-12 00:43:168214 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578215 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088216 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578217 response->response_time = base::Time::Now();
8218 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068219
8220 { // Setup state for response_.vary_data
8221 HttpRequestInfo request;
8222 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8223 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278224 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438225 request.extra_headers.SetHeader("Foo", "1");
8226 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508227 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068228 }
8229
8230 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168231 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068232
8233 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168234 EXPECT_FALSE(trans.read_buf_);
8235 EXPECT_EQ(0, trans.read_buf_len_);
8236 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528237 EXPECT_FALSE(response->auth_challenge);
8238 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048239 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088240 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578241 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068242}
8243
[email protected]bacff652009-03-31 17:50:338244// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018245TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338246 HttpRequestInfo request;
8247 request.method = "GET";
bncce36dca22015-04-21 22:11:238248 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338249
danakj1fd259a02016-04-16 03:17:098250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168251 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278252
[email protected]bacff652009-03-31 17:50:338253 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238254 MockWrite(
8255 "GET / HTTP/1.1\r\n"
8256 "Host: www.example.org\r\n"
8257 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338258 };
8259
8260 MockRead data_reads[] = {
8261 MockRead("HTTP/1.0 200 OK\r\n"),
8262 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8263 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068264 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338265 };
8266
[email protected]5ecc992a42009-11-11 01:41:598267 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:398268 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8269 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068270 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8271 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338272
[email protected]bb88e1d32013-05-03 23:11:078273 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8274 session_deps_.socket_factory->AddSocketDataProvider(&data);
8275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338277
[email protected]49639fa2011-12-20 23:22:418278 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338279
tfarina42834112016-09-22 13:38:208280 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338282
8283 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018284 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338285
bnc691fda62016-08-12 00:43:168286 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018287 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338288
8289 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018290 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338291
bnc691fda62016-08-12 00:43:168292 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338293
wezca1070932016-05-26 20:30:528294 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338295 EXPECT_EQ(100, response->headers->GetContentLength());
8296}
8297
8298// Test HTTPS connections to a site with a bad certificate, going through a
8299// proxy
bncd16676a2016-07-20 16:23:018300TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598301 session_deps_.proxy_resolution_service =
8302 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:338303
8304 HttpRequestInfo request;
8305 request.method = "GET";
bncce36dca22015-04-21 22:11:238306 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:338307
8308 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178309 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8310 "Host: www.example.org:443\r\n"
8311 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338312 };
8313
8314 MockRead proxy_reads[] = {
8315 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068316 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338317 };
8318
8319 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178320 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8321 "Host: www.example.org:443\r\n"
8322 "Proxy-Connection: keep-alive\r\n\r\n"),
8323 MockWrite("GET / HTTP/1.1\r\n"
8324 "Host: www.example.org\r\n"
8325 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338326 };
8327
8328 MockRead data_reads[] = {
8329 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8330 MockRead("HTTP/1.0 200 OK\r\n"),
8331 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8332 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068333 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338334 };
8335
[email protected]31a2bfe2010-02-09 08:03:398336 StaticSocketDataProvider ssl_bad_certificate(
8337 proxy_reads, arraysize(proxy_reads),
8338 proxy_writes, arraysize(proxy_writes));
8339 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8340 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068341 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8342 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338343
[email protected]bb88e1d32013-05-03 23:11:078344 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8345 session_deps_.socket_factory->AddSocketDataProvider(&data);
8346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8347 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338348
[email protected]49639fa2011-12-20 23:22:418349 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338350
8351 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078352 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338353
danakj1fd259a02016-04-16 03:17:098354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338356
tfarina42834112016-09-22 13:38:208357 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338359
8360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018361 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338362
bnc691fda62016-08-12 00:43:168363 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338365
8366 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018367 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338368
bnc691fda62016-08-12 00:43:168369 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338370
wezca1070932016-05-26 20:30:528371 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338372 EXPECT_EQ(100, response->headers->GetContentLength());
8373 }
8374}
8375
[email protected]2df19bb2010-08-25 20:13:468376
8377// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018378TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598379 session_deps_.proxy_resolution_service =
8380 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518381 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078382 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468383
8384 HttpRequestInfo request;
8385 request.method = "GET";
bncce36dca22015-04-21 22:11:238386 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468387
8388 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178389 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8390 "Host: www.example.org:443\r\n"
8391 "Proxy-Connection: keep-alive\r\n\r\n"),
8392 MockWrite("GET / HTTP/1.1\r\n"
8393 "Host: www.example.org\r\n"
8394 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468395 };
8396
8397 MockRead data_reads[] = {
8398 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8399 MockRead("HTTP/1.1 200 OK\r\n"),
8400 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8401 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068402 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468403 };
8404
8405 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8406 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068407 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8408 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468409
[email protected]bb88e1d32013-05-03 23:11:078410 session_deps_.socket_factory->AddSocketDataProvider(&data);
8411 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8412 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468413
[email protected]49639fa2011-12-20 23:22:418414 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468415
danakj1fd259a02016-04-16 03:17:098416 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468418
tfarina42834112016-09-22 13:38:208419 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468421
8422 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018423 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168424 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468425
wezca1070932016-05-26 20:30:528426 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468427
tbansal2ecbbc72016-10-06 17:15:478428 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468429 EXPECT_TRUE(response->headers->IsKeepAlive());
8430 EXPECT_EQ(200, response->headers->response_code());
8431 EXPECT_EQ(100, response->headers->GetContentLength());
8432 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208433
8434 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168435 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208436 TestLoadTimingNotReusedWithPac(load_timing_info,
8437 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468438}
8439
[email protected]511f6f52010-12-17 03:58:298440// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018441TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598442 session_deps_.proxy_resolution_service =
8443 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518444 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078445 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298446
8447 HttpRequestInfo request;
8448 request.method = "GET";
bncce36dca22015-04-21 22:11:238449 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298450
8451 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178452 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8453 "Host: www.example.org:443\r\n"
8454 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298455 };
8456
8457 MockRead data_reads[] = {
8458 MockRead("HTTP/1.1 302 Redirect\r\n"),
8459 MockRead("Location: http://login.example.com/\r\n"),
8460 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068461 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298462 };
8463
8464 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8465 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068466 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298467
[email protected]bb88e1d32013-05-03 23:11:078468 session_deps_.socket_factory->AddSocketDataProvider(&data);
8469 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298470
[email protected]49639fa2011-12-20 23:22:418471 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298472
danakj1fd259a02016-04-16 03:17:098473 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298475
tfarina42834112016-09-22 13:38:208476 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298478
8479 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018480 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168481 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298482
wezca1070932016-05-26 20:30:528483 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298484
8485 EXPECT_EQ(302, response->headers->response_code());
8486 std::string url;
8487 EXPECT_TRUE(response->headers->IsRedirect(&url));
8488 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208489
8490 // In the case of redirects from proxies, HttpNetworkTransaction returns
8491 // timing for the proxy connection instead of the connection to the host,
8492 // and no send / receive times.
8493 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8494 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168495 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208496
8497 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198498 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208499
8500 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8501 EXPECT_LE(load_timing_info.proxy_resolve_start,
8502 load_timing_info.proxy_resolve_end);
8503 EXPECT_LE(load_timing_info.proxy_resolve_end,
8504 load_timing_info.connect_timing.connect_start);
8505 ExpectConnectTimingHasTimes(
8506 load_timing_info.connect_timing,
8507 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8508
8509 EXPECT_TRUE(load_timing_info.send_start.is_null());
8510 EXPECT_TRUE(load_timing_info.send_end.is_null());
8511 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298512}
8513
8514// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018515TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598516 session_deps_.proxy_resolution_service =
8517 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298518
8519 HttpRequestInfo request;
8520 request.method = "GET";
bncce36dca22015-04-21 22:11:238521 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298522
bncdf80d44fd2016-07-15 20:27:418523 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238524 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418525 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088526 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298527 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418528 CreateMockWrite(conn, 0, SYNCHRONOUS),
8529 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298530 };
8531
8532 static const char* const kExtraHeaders[] = {
8533 "location",
8534 "http://login.example.com/",
8535 };
bnc42331402016-07-25 13:36:158536 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238537 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298538 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418539 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298540 };
8541
rch8e6c6c42015-05-01 14:05:138542 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8543 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068544 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368545 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298546
[email protected]bb88e1d32013-05-03 23:11:078547 session_deps_.socket_factory->AddSocketDataProvider(&data);
8548 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298549
[email protected]49639fa2011-12-20 23:22:418550 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298551
danakj1fd259a02016-04-16 03:17:098552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298554
tfarina42834112016-09-22 13:38:208555 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298557
8558 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018559 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168560 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298561
wezca1070932016-05-26 20:30:528562 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298563
8564 EXPECT_EQ(302, response->headers->response_code());
8565 std::string url;
8566 EXPECT_TRUE(response->headers->IsRedirect(&url));
8567 EXPECT_EQ("http://login.example.com/", url);
8568}
8569
[email protected]4eddbc732012-08-09 05:40:178570// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018571TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598572 session_deps_.proxy_resolution_service =
8573 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298574
8575 HttpRequestInfo request;
8576 request.method = "GET";
bncce36dca22015-04-21 22:11:238577 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298578
8579 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178580 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8581 "Host: www.example.org:443\r\n"
8582 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298583 };
8584
8585 MockRead data_reads[] = {
8586 MockRead("HTTP/1.1 404 Not Found\r\n"),
8587 MockRead("Content-Length: 23\r\n\r\n"),
8588 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068589 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298590 };
8591
8592 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8593 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068594 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298595
[email protected]bb88e1d32013-05-03 23:11:078596 session_deps_.socket_factory->AddSocketDataProvider(&data);
8597 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298598
[email protected]49639fa2011-12-20 23:22:418599 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298600
danakj1fd259a02016-04-16 03:17:098601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298603
tfarina42834112016-09-22 13:38:208604 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298606
8607 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018608 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298609
ttuttle960fcbf2016-04-19 13:26:328610 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298611}
8612
[email protected]4eddbc732012-08-09 05:40:178613// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018614TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598615 session_deps_.proxy_resolution_service =
8616 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298617
8618 HttpRequestInfo request;
8619 request.method = "GET";
bncce36dca22015-04-21 22:11:238620 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298621
bncdf80d44fd2016-07-15 20:27:418622 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238623 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418624 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088625 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298626 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418627 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298628 };
8629
8630 static const char* const kExtraHeaders[] = {
8631 "location",
8632 "http://login.example.com/",
8633 };
bnc42331402016-07-25 13:36:158634 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238635 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418636 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558637 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298638 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418639 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138640 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298641 };
8642
rch8e6c6c42015-05-01 14:05:138643 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8644 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068645 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368646 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298647
[email protected]bb88e1d32013-05-03 23:11:078648 session_deps_.socket_factory->AddSocketDataProvider(&data);
8649 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298650
[email protected]49639fa2011-12-20 23:22:418651 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298652
danakj1fd259a02016-04-16 03:17:098653 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168654 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298655
tfarina42834112016-09-22 13:38:208656 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298658
8659 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018660 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298661
ttuttle960fcbf2016-04-19 13:26:328662 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298663}
8664
[email protected]0c5fb722012-02-28 11:50:358665// Test the request-challenge-retry sequence for basic auth, through
8666// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018667TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358668 HttpRequestInfo request;
8669 request.method = "GET";
bncce36dca22015-04-21 22:11:238670 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358671 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298672 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358673
8674 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598675 session_deps_.proxy_resolution_service =
8676 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518677 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078678 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098679 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358680
8681 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418682 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238683 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418684 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088685 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388686 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358687
bnc691fda62016-08-12 00:43:168688 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358689 // be issuing -- the final header line contains the credentials.
8690 const char* const kAuthCredentials[] = {
8691 "proxy-authorization", "Basic Zm9vOmJhcg==",
8692 };
bncdf80d44fd2016-07-15 20:27:418693 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348694 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238695 HostPortPair("www.example.org", 443)));
8696 // fetch https://www.example.org/ via HTTP
8697 const char get[] =
8698 "GET / HTTP/1.1\r\n"
8699 "Host: www.example.org\r\n"
8700 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418701 SpdySerializedFrame wrapped_get(
8702 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358703
8704 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418705 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8706 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358707 };
8708
8709 // The proxy responds to the connect with a 407, using a persistent
8710 // connection.
thestig9d3bb0c2015-01-24 00:49:518711 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358712 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358713 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8714 };
bnc42331402016-07-25 13:36:158715 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418716 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358717
bnc42331402016-07-25 13:36:158718 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358719 const char resp[] = "HTTP/1.1 200 OK\r\n"
8720 "Content-Length: 5\r\n\r\n";
8721
bncdf80d44fd2016-07-15 20:27:418722 SpdySerializedFrame wrapped_get_resp(
8723 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8724 SpdySerializedFrame wrapped_body(
8725 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358726 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418727 CreateMockRead(conn_auth_resp, 1, ASYNC),
8728 CreateMockRead(conn_resp, 4, ASYNC),
8729 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8730 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138731 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358732 };
8733
rch8e6c6c42015-05-01 14:05:138734 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8735 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078736 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358737 // Negotiate SPDY to the proxy
8738 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368739 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078740 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358741 // Vanilla SSL to the server
8742 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078743 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358744
8745 TestCompletionCallback callback1;
8746
bnc87dcefc2017-05-25 12:47:588747 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198748 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358749
8750 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358752
8753 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018754 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468755 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358756 log.GetEntries(&entries);
8757 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008758 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8759 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358760 ExpectLogContainsSomewhere(
8761 entries, pos,
mikecirone8b85c432016-09-08 19:11:008762 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8763 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358764
8765 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528766 ASSERT_TRUE(response);
8767 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358768 EXPECT_EQ(407, response->headers->response_code());
8769 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528770 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438771 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358772
8773 TestCompletionCallback callback2;
8774
8775 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8776 callback2.callback());
robpercival214763f2016-07-01 23:27:018777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358778
8779 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018780 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358781
8782 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528783 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358784
8785 EXPECT_TRUE(response->headers->IsKeepAlive());
8786 EXPECT_EQ(200, response->headers->response_code());
8787 EXPECT_EQ(5, response->headers->GetContentLength());
8788 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8789
8790 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528791 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358792
[email protected]029c83b62013-01-24 05:28:208793 LoadTimingInfo load_timing_info;
8794 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8795 TestLoadTimingNotReusedWithPac(load_timing_info,
8796 CONNECT_TIMING_HAS_SSL_TIMES);
8797
[email protected]0c5fb722012-02-28 11:50:358798 trans.reset();
8799 session->CloseAllConnections();
8800}
8801
[email protected]7c6f7ba2012-04-03 04:09:298802// Test that an explicitly trusted SPDY proxy can push a resource from an
8803// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018804TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158805 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198806 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158807 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8808 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298809 HttpRequestInfo request;
8810 HttpRequestInfo push_request;
8811
[email protected]7c6f7ba2012-04-03 04:09:298812 request.method = "GET";
bncce36dca22015-04-21 22:11:238813 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298814 push_request.method = "GET";
8815 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8816
tbansal28e68f82016-02-04 02:56:158817 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:598818 session_deps_.proxy_resolution_service =
8819 ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518820 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078821 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508822
inlinechan894515af2016-12-09 02:40:108823 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508824
danakj1fd259a02016-04-16 03:17:098825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298826
bncdf80d44fd2016-07-15 20:27:418827 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458828 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358829 SpdySerializedFrame stream2_priority(
8830 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298831
8832 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418833 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358834 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298835 };
8836
Bence Béky7bf94362018-01-10 13:19:368837 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
8838 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
8839
bncdf80d44fd2016-07-15 20:27:418840 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158841 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298842
bncdf80d44fd2016-07-15 20:27:418843 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298844
[email protected]8a0fc822013-06-27 20:52:438845 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418846 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8847 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298848
8849 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:368850 CreateMockRead(stream2_syn, 1, ASYNC),
8851 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358852 CreateMockRead(stream1_body, 4, ASYNC),
8853 CreateMockRead(stream2_body, 5, ASYNC),
8854 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298855 };
8856
rch8e6c6c42015-05-01 14:05:138857 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8858 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078859 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298860 // Negotiate SPDY to the proxy
8861 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368862 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078863 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298864
bnc87dcefc2017-05-25 12:47:588865 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198866 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298867 TestCompletionCallback callback;
8868 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298870
8871 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018872 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298873 const HttpResponseInfo* response = trans->GetResponseInfo();
8874
bnc87dcefc2017-05-25 12:47:588875 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198876 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508877 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298879
8880 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018881 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298882 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8883
wezca1070932016-05-26 20:30:528884 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298885 EXPECT_TRUE(response->headers->IsKeepAlive());
8886
8887 EXPECT_EQ(200, response->headers->response_code());
8888 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8889
8890 std::string response_data;
8891 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018892 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298893 EXPECT_EQ("hello!", response_data);
8894
[email protected]029c83b62013-01-24 05:28:208895 LoadTimingInfo load_timing_info;
8896 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8897 TestLoadTimingNotReusedWithPac(load_timing_info,
8898 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8899
[email protected]7c6f7ba2012-04-03 04:09:298900 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528901 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298902 EXPECT_EQ(200, push_response->headers->response_code());
8903
8904 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018905 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298906 EXPECT_EQ("pushed", response_data);
8907
[email protected]029c83b62013-01-24 05:28:208908 LoadTimingInfo push_load_timing_info;
8909 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8910 TestLoadTimingReusedWithPac(push_load_timing_info);
8911 // The transactions should share a socket ID, despite being for different
8912 // origins.
8913 EXPECT_EQ(load_timing_info.socket_log_id,
8914 push_load_timing_info.socket_log_id);
8915
[email protected]7c6f7ba2012-04-03 04:09:298916 trans.reset();
8917 push_trans.reset();
8918 session->CloseAllConnections();
8919}
8920
[email protected]8c843192012-04-05 07:15:008921// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018922TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158923 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198924 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158925 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8926 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008927 HttpRequestInfo request;
8928
8929 request.method = "GET";
bncce36dca22015-04-21 22:11:238930 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008931
Lily Houghton8c2f97d2018-01-22 05:06:598932 session_deps_.proxy_resolution_service =
8933 ProxyResolutionService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518934 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078935 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508936
8937 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108938 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508939
danakj1fd259a02016-04-16 03:17:098940 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008941
bncdf80d44fd2016-07-15 20:27:418942 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458943 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008944
bncdf80d44fd2016-07-15 20:27:418945 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088946 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008947
8948 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418949 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008950 };
8951
bncdf80d44fd2016-07-15 20:27:418952 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158953 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008954
bncdf80d44fd2016-07-15 20:27:418955 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008956
bncdf80d44fd2016-07-15 20:27:418957 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558958 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008959
8960 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418961 CreateMockRead(stream1_reply, 1, ASYNC),
8962 CreateMockRead(stream2_syn, 2, ASYNC),
8963 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598964 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008965 };
8966
rch8e6c6c42015-05-01 14:05:138967 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8968 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078969 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008970 // Negotiate SPDY to the proxy
8971 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368972 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078973 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008974
bnc87dcefc2017-05-25 12:47:588975 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198976 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008977 TestCompletionCallback callback;
8978 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008980
8981 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018982 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008983 const HttpResponseInfo* response = trans->GetResponseInfo();
8984
wezca1070932016-05-26 20:30:528985 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008986 EXPECT_TRUE(response->headers->IsKeepAlive());
8987
8988 EXPECT_EQ(200, response->headers->response_code());
8989 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8990
8991 std::string response_data;
8992 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018993 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008994 EXPECT_EQ("hello!", response_data);
8995
8996 trans.reset();
8997 session->CloseAllConnections();
8998}
8999
tbansal8ef1d3e2016-02-03 04:05:429000// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9001// resources.
bncd16676a2016-07-20 16:23:019002TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159003 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199004 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159005 proxy_delegate->set_trusted_spdy_proxy(
9006 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9007
tbansal8ef1d3e2016-02-03 04:05:429008 HttpRequestInfo request;
9009
9010 request.method = "GET";
9011 request.url = GURL("http://www.example.org/");
9012
9013 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599014 session_deps_.proxy_resolution_service =
9015 ProxyResolutionService::CreateFixed("https://myproxy:70");
tbansal8ef1d3e2016-02-03 04:05:429016 BoundTestNetLog log;
9017 session_deps_.net_log = log.bound().net_log();
9018
9019 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109020 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429021
danakj1fd259a02016-04-16 03:17:099022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429023
bncdf80d44fd2016-07-15 20:27:419024 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459025 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:359026 SpdySerializedFrame stream2_priority(
9027 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429028
9029 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419030 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359031 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429032 };
9033
bncdf80d44fd2016-07-15 20:27:419034 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159035 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429036
bncdf80d44fd2016-07-15 20:27:419037 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339038 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499039
bncdf80d44fd2016-07-15 20:27:419040 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429041
bncdf80d44fd2016-07-15 20:27:419042 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159043 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429044
bncdf80d44fd2016-07-15 20:27:419045 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429046
9047 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419048 CreateMockRead(stream1_reply, 1, ASYNC),
9049 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359050 CreateMockRead(stream1_body, 4, ASYNC),
9051 CreateMockRead(stream2_body, 5, ASYNC),
9052 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429053 };
9054
9055 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9056 arraysize(spdy_writes));
9057 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9058 // Negotiate SPDY to the proxy
9059 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369060 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429061 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9062
bnc87dcefc2017-05-25 12:47:589063 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199064 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429065 TestCompletionCallback callback;
9066 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429068
9069 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019070 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429071 const HttpResponseInfo* response = trans->GetResponseInfo();
9072
wezca1070932016-05-26 20:30:529073 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429074 EXPECT_TRUE(response->headers->IsKeepAlive());
9075
9076 EXPECT_EQ(200, response->headers->response_code());
9077 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9078
9079 std::string response_data;
9080 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019081 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429082 EXPECT_EQ("hello!", response_data);
9083
9084 trans.reset();
9085 session->CloseAllConnections();
9086}
9087
[email protected]2df19bb2010-08-25 20:13:469088// Test HTTPS connections to a site with a bad certificate, going through an
9089// HTTPS proxy
bncd16676a2016-07-20 16:23:019090TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599091 session_deps_.proxy_resolution_service =
9092 ProxyResolutionService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:469093
9094 HttpRequestInfo request;
9095 request.method = "GET";
bncce36dca22015-04-21 22:11:239096 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:469097
9098 // Attempt to fetch the URL from a server with a bad cert
9099 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179100 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9101 "Host: www.example.org:443\r\n"
9102 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469103 };
9104
9105 MockRead bad_cert_reads[] = {
9106 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069107 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469108 };
9109
9110 // Attempt to fetch the URL with a good cert
9111 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179112 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9113 "Host: www.example.org:443\r\n"
9114 "Proxy-Connection: keep-alive\r\n\r\n"),
9115 MockWrite("GET / HTTP/1.1\r\n"
9116 "Host: www.example.org\r\n"
9117 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469118 };
9119
9120 MockRead good_cert_reads[] = {
9121 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9122 MockRead("HTTP/1.0 200 OK\r\n"),
9123 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9124 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069125 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469126 };
9127
9128 StaticSocketDataProvider ssl_bad_certificate(
9129 bad_cert_reads, arraysize(bad_cert_reads),
9130 bad_cert_writes, arraysize(bad_cert_writes));
9131 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
9132 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:069133 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9134 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469135
9136 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9138 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469140
9141 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079142 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9143 session_deps_.socket_factory->AddSocketDataProvider(&data);
9144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469145
[email protected]49639fa2011-12-20 23:22:419146 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469147
danakj1fd259a02016-04-16 03:17:099148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169149 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469150
tfarina42834112016-09-22 13:38:209151 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469153
9154 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019155 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469156
bnc691fda62016-08-12 00:43:169157 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469159
9160 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019161 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469162
bnc691fda62016-08-12 00:43:169163 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469164
wezca1070932016-05-26 20:30:529165 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469166 EXPECT_EQ(100, response->headers->GetContentLength());
9167}
9168
bncd16676a2016-07-20 16:23:019169TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429170 HttpRequestInfo request;
9171 request.method = "GET";
bncce36dca22015-04-21 22:11:239172 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439173 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9174 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:429175
danakj1fd259a02016-04-16 03:17:099176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279178
[email protected]1c773ea12009-04-28 19:58:429179 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239180 MockWrite(
9181 "GET / HTTP/1.1\r\n"
9182 "Host: www.example.org\r\n"
9183 "Connection: keep-alive\r\n"
9184 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429185 };
9186
9187 // Lastly, the server responds with the actual content.
9188 MockRead data_reads[] = {
9189 MockRead("HTTP/1.0 200 OK\r\n"),
9190 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9191 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069192 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429193 };
9194
[email protected]31a2bfe2010-02-09 08:03:399195 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9196 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079197 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429198
[email protected]49639fa2011-12-20 23:22:419199 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429200
tfarina42834112016-09-22 13:38:209201 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429203
9204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019205 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429206}
9207
bncd16676a2016-07-20 16:23:019208TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299209 HttpRequestInfo request;
9210 request.method = "GET";
bncce36dca22015-04-21 22:11:239211 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299212 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9213 "Chromium Ultra Awesome X Edition");
9214
Lily Houghton8c2f97d2018-01-22 05:06:599215 session_deps_.proxy_resolution_service =
9216 ProxyResolutionService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:099217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279219
[email protected]da81f132010-08-18 23:39:299220 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179221 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9222 "Host: www.example.org:443\r\n"
9223 "Proxy-Connection: keep-alive\r\n"
9224 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299225 };
9226 MockRead data_reads[] = {
9227 // Return an error, so the transaction stops here (this test isn't
9228 // interested in the rest).
9229 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9230 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9231 MockRead("Proxy-Connection: close\r\n\r\n"),
9232 };
9233
9234 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9235 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079236 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299237
[email protected]49639fa2011-12-20 23:22:419238 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299239
tfarina42834112016-09-22 13:38:209240 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299242
9243 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019244 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299245}
9246
bncd16676a2016-07-20 16:23:019247TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429248 HttpRequestInfo request;
9249 request.method = "GET";
bncce36dca22015-04-21 22:11:239250 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169251 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9252 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:429253
danakj1fd259a02016-04-16 03:17:099254 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279256
[email protected]1c773ea12009-04-28 19:58:429257 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239258 MockWrite(
9259 "GET / HTTP/1.1\r\n"
9260 "Host: www.example.org\r\n"
9261 "Connection: keep-alive\r\n"
9262 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429263 };
9264
9265 // Lastly, the server responds with the actual content.
9266 MockRead data_reads[] = {
9267 MockRead("HTTP/1.0 200 OK\r\n"),
9268 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9269 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069270 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429271 };
9272
[email protected]31a2bfe2010-02-09 08:03:399273 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9274 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079275 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429276
[email protected]49639fa2011-12-20 23:22:419277 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429278
tfarina42834112016-09-22 13:38:209279 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429281
9282 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019283 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429284}
9285
bncd16676a2016-07-20 16:23:019286TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429287 HttpRequestInfo request;
9288 request.method = "POST";
bncce36dca22015-04-21 22:11:239289 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429290
danakj1fd259a02016-04-16 03:17:099291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279293
[email protected]1c773ea12009-04-28 19:58:429294 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239295 MockWrite(
9296 "POST / HTTP/1.1\r\n"
9297 "Host: www.example.org\r\n"
9298 "Connection: keep-alive\r\n"
9299 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429300 };
9301
9302 // Lastly, the server responds with the actual content.
9303 MockRead data_reads[] = {
9304 MockRead("HTTP/1.0 200 OK\r\n"),
9305 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9306 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069307 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429308 };
9309
[email protected]31a2bfe2010-02-09 08:03:399310 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9311 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079312 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429313
[email protected]49639fa2011-12-20 23:22:419314 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429315
tfarina42834112016-09-22 13:38:209316 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429318
9319 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019320 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429321}
9322
bncd16676a2016-07-20 16:23:019323TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429324 HttpRequestInfo request;
9325 request.method = "PUT";
bncce36dca22015-04-21 22:11:239326 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429327
danakj1fd259a02016-04-16 03:17:099328 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169329 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279330
[email protected]1c773ea12009-04-28 19:58:429331 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239332 MockWrite(
9333 "PUT / HTTP/1.1\r\n"
9334 "Host: www.example.org\r\n"
9335 "Connection: keep-alive\r\n"
9336 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429337 };
9338
9339 // Lastly, the server responds with the actual content.
9340 MockRead data_reads[] = {
9341 MockRead("HTTP/1.0 200 OK\r\n"),
9342 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9343 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069344 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429345 };
9346
[email protected]31a2bfe2010-02-09 08:03:399347 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9348 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079349 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429350
[email protected]49639fa2011-12-20 23:22:419351 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429352
tfarina42834112016-09-22 13:38:209353 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429355
9356 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019357 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429358}
9359
bncd16676a2016-07-20 16:23:019360TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429361 HttpRequestInfo request;
9362 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239363 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429364
danakj1fd259a02016-04-16 03:17:099365 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279367
[email protected]1c773ea12009-04-28 19:58:429368 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139369 MockWrite("HEAD / HTTP/1.1\r\n"
9370 "Host: www.example.org\r\n"
9371 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429372 };
9373
9374 // Lastly, the server responds with the actual content.
9375 MockRead data_reads[] = {
9376 MockRead("HTTP/1.0 200 OK\r\n"),
9377 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9378 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069379 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429380 };
9381
[email protected]31a2bfe2010-02-09 08:03:399382 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9383 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429385
[email protected]49639fa2011-12-20 23:22:419386 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429387
tfarina42834112016-09-22 13:38:209388 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429390
9391 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019392 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429393}
9394
bncd16676a2016-07-20 16:23:019395TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429396 HttpRequestInfo request;
9397 request.method = "GET";
bncce36dca22015-04-21 22:11:239398 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429399 request.load_flags = LOAD_BYPASS_CACHE;
9400
danakj1fd259a02016-04-16 03:17:099401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279403
[email protected]1c773ea12009-04-28 19:58:429404 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239405 MockWrite(
9406 "GET / HTTP/1.1\r\n"
9407 "Host: www.example.org\r\n"
9408 "Connection: keep-alive\r\n"
9409 "Pragma: no-cache\r\n"
9410 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429411 };
9412
9413 // Lastly, the server responds with the actual content.
9414 MockRead data_reads[] = {
9415 MockRead("HTTP/1.0 200 OK\r\n"),
9416 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9417 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069418 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429419 };
9420
[email protected]31a2bfe2010-02-09 08:03:399421 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9422 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079423 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429424
[email protected]49639fa2011-12-20 23:22:419425 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429426
tfarina42834112016-09-22 13:38:209427 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429429
9430 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019431 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429432}
9433
bncd16676a2016-07-20 16:23:019434TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429435 HttpRequestInfo request;
9436 request.method = "GET";
bncce36dca22015-04-21 22:11:239437 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429438 request.load_flags = LOAD_VALIDATE_CACHE;
9439
danakj1fd259a02016-04-16 03:17:099440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279442
[email protected]1c773ea12009-04-28 19:58:429443 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239444 MockWrite(
9445 "GET / HTTP/1.1\r\n"
9446 "Host: www.example.org\r\n"
9447 "Connection: keep-alive\r\n"
9448 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429449 };
9450
9451 // Lastly, the server responds with the actual content.
9452 MockRead data_reads[] = {
9453 MockRead("HTTP/1.0 200 OK\r\n"),
9454 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9455 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069456 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429457 };
9458
[email protected]31a2bfe2010-02-09 08:03:399459 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9460 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079461 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429462
[email protected]49639fa2011-12-20 23:22:419463 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429464
tfarina42834112016-09-22 13:38:209465 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429467
9468 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019469 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429470}
9471
bncd16676a2016-07-20 16:23:019472TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429473 HttpRequestInfo request;
9474 request.method = "GET";
bncce36dca22015-04-21 22:11:239475 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439476 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:429477
danakj1fd259a02016-04-16 03:17:099478 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169479 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279480
[email protected]1c773ea12009-04-28 19:58:429481 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239482 MockWrite(
9483 "GET / HTTP/1.1\r\n"
9484 "Host: www.example.org\r\n"
9485 "Connection: keep-alive\r\n"
9486 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429487 };
9488
9489 // Lastly, the server responds with the actual content.
9490 MockRead data_reads[] = {
9491 MockRead("HTTP/1.0 200 OK\r\n"),
9492 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9493 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069494 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429495 };
9496
[email protected]31a2bfe2010-02-09 08:03:399497 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9498 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079499 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429500
[email protected]49639fa2011-12-20 23:22:419501 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429502
tfarina42834112016-09-22 13:38:209503 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019504 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429505
9506 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019507 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429508}
9509
bncd16676a2016-07-20 16:23:019510TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479511 HttpRequestInfo request;
9512 request.method = "GET";
bncce36dca22015-04-21 22:11:239513 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439514 request.extra_headers.SetHeader("referer", "www.foo.com");
9515 request.extra_headers.SetHeader("hEllo", "Kitty");
9516 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:479517
danakj1fd259a02016-04-16 03:17:099518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169519 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279520
[email protected]270c6412010-03-29 22:02:479521 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239522 MockWrite(
9523 "GET / HTTP/1.1\r\n"
9524 "Host: www.example.org\r\n"
9525 "Connection: keep-alive\r\n"
9526 "referer: www.foo.com\r\n"
9527 "hEllo: Kitty\r\n"
9528 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479529 };
9530
9531 // Lastly, the server responds with the actual content.
9532 MockRead data_reads[] = {
9533 MockRead("HTTP/1.0 200 OK\r\n"),
9534 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9535 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069536 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479537 };
9538
9539 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9540 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079541 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479542
[email protected]49639fa2011-12-20 23:22:419543 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479544
tfarina42834112016-09-22 13:38:209545 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479547
9548 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019549 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479550}
9551
bncd16676a2016-07-20 16:23:019552TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279553 HttpRequestInfo request;
9554 request.method = "GET";
bncce36dca22015-04-21 22:11:239555 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279556
Lily Houghton8c2f97d2018-01-22 05:06:599557 session_deps_.proxy_resolution_service =
9558 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519559 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079560 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029561
danakj1fd259a02016-04-16 03:17:099562 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169563 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029564
[email protected]3cd17242009-06-23 02:59:029565 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9566 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9567
9568 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239569 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9570 MockWrite(
9571 "GET / HTTP/1.1\r\n"
9572 "Host: www.example.org\r\n"
9573 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029574
9575 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069576 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029577 MockRead("HTTP/1.0 200 OK\r\n"),
9578 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9579 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069580 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029581 };
9582
[email protected]31a2bfe2010-02-09 08:03:399583 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9584 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079585 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029586
[email protected]49639fa2011-12-20 23:22:419587 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029588
tfarina42834112016-09-22 13:38:209589 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029591
9592 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019593 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029594
bnc691fda62016-08-12 00:43:169595 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529596 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029597
tbansal2ecbbc72016-10-06 17:15:479598 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209599 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169600 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209601 TestLoadTimingNotReusedWithPac(load_timing_info,
9602 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9603
[email protected]3cd17242009-06-23 02:59:029604 std::string response_text;
bnc691fda62016-08-12 00:43:169605 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019606 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029607 EXPECT_EQ("Payload", response_text);
9608}
9609
bncd16676a2016-07-20 16:23:019610TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279611 HttpRequestInfo request;
9612 request.method = "GET";
bncce36dca22015-04-21 22:11:239613 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279614
Lily Houghton8c2f97d2018-01-22 05:06:599615 session_deps_.proxy_resolution_service =
9616 ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519617 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079618 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029619
danakj1fd259a02016-04-16 03:17:099620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029622
[email protected]3cd17242009-06-23 02:59:029623 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9624 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9625
9626 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239627 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9628 arraysize(write_buffer)),
9629 MockWrite(
9630 "GET / HTTP/1.1\r\n"
9631 "Host: www.example.org\r\n"
9632 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029633
9634 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019635 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9636 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359637 MockRead("HTTP/1.0 200 OK\r\n"),
9638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9639 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069640 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359641 };
9642
[email protected]31a2bfe2010-02-09 08:03:399643 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9644 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079645 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359646
[email protected]8ddf8322012-02-23 18:08:069647 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359649
[email protected]49639fa2011-12-20 23:22:419650 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359651
tfarina42834112016-09-22 13:38:209652 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359654
9655 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019656 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359657
[email protected]029c83b62013-01-24 05:28:209658 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169659 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209660 TestLoadTimingNotReusedWithPac(load_timing_info,
9661 CONNECT_TIMING_HAS_SSL_TIMES);
9662
bnc691fda62016-08-12 00:43:169663 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529664 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479665 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359666
9667 std::string response_text;
bnc691fda62016-08-12 00:43:169668 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019669 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359670 EXPECT_EQ("Payload", response_text);
9671}
9672
bncd16676a2016-07-20 16:23:019673TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209674 HttpRequestInfo request;
9675 request.method = "GET";
bncce36dca22015-04-21 22:11:239676 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209677
Lily Houghton8c2f97d2018-01-22 05:06:599678 session_deps_.proxy_resolution_service =
9679 ProxyResolutionService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519680 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079681 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209682
danakj1fd259a02016-04-16 03:17:099683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209685
9686 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9687 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9688
9689 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239690 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9691 MockWrite(
9692 "GET / HTTP/1.1\r\n"
9693 "Host: www.example.org\r\n"
9694 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209695
9696 MockRead data_reads[] = {
9697 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9698 MockRead("HTTP/1.0 200 OK\r\n"),
9699 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9700 MockRead("Payload"),
9701 MockRead(SYNCHRONOUS, OK)
9702 };
9703
9704 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9705 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079706 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209707
9708 TestCompletionCallback callback;
9709
tfarina42834112016-09-22 13:38:209710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209712
9713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019714 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209715
bnc691fda62016-08-12 00:43:169716 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529717 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209718
9719 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169720 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209721 TestLoadTimingNotReused(load_timing_info,
9722 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9723
9724 std::string response_text;
bnc691fda62016-08-12 00:43:169725 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019726 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209727 EXPECT_EQ("Payload", response_text);
9728}
9729
bncd16676a2016-07-20 16:23:019730TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279731 HttpRequestInfo request;
9732 request.method = "GET";
bncce36dca22015-04-21 22:11:239733 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279734
Lily Houghton8c2f97d2018-01-22 05:06:599735 session_deps_.proxy_resolution_service =
9736 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519737 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079738 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359739
danakj1fd259a02016-04-16 03:17:099740 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359742
[email protected]e0c27be2009-07-15 13:09:359743 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9744 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379745 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239746 0x05, // Version
9747 0x01, // Command (CONNECT)
9748 0x00, // Reserved.
9749 0x03, // Address type (DOMAINNAME).
9750 0x0F, // Length of domain (15)
9751 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9752 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379753 };
[email protected]e0c27be2009-07-15 13:09:359754 const char kSOCKS5OkResponse[] =
9755 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9756
9757 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239758 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9759 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9760 MockWrite(
9761 "GET / HTTP/1.1\r\n"
9762 "Host: www.example.org\r\n"
9763 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359764
9765 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019766 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9767 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359768 MockRead("HTTP/1.0 200 OK\r\n"),
9769 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9770 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069771 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359772 };
9773
[email protected]31a2bfe2010-02-09 08:03:399774 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9775 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079776 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359777
[email protected]49639fa2011-12-20 23:22:419778 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359779
tfarina42834112016-09-22 13:38:209780 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359782
9783 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019784 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359785
bnc691fda62016-08-12 00:43:169786 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529787 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479788 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359789
[email protected]029c83b62013-01-24 05:28:209790 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169791 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209792 TestLoadTimingNotReusedWithPac(load_timing_info,
9793 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9794
[email protected]e0c27be2009-07-15 13:09:359795 std::string response_text;
bnc691fda62016-08-12 00:43:169796 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019797 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359798 EXPECT_EQ("Payload", response_text);
9799}
9800
bncd16676a2016-07-20 16:23:019801TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279802 HttpRequestInfo request;
9803 request.method = "GET";
bncce36dca22015-04-21 22:11:239804 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279805
Lily Houghton8c2f97d2018-01-22 05:06:599806 session_deps_.proxy_resolution_service =
9807 ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519808 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079809 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359810
danakj1fd259a02016-04-16 03:17:099811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359813
[email protected]e0c27be2009-07-15 13:09:359814 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9815 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379816 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239817 0x05, // Version
9818 0x01, // Command (CONNECT)
9819 0x00, // Reserved.
9820 0x03, // Address type (DOMAINNAME).
9821 0x0F, // Length of domain (15)
9822 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9823 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379824 };
9825
[email protected]e0c27be2009-07-15 13:09:359826 const char kSOCKS5OkResponse[] =
9827 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9828
9829 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239830 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9831 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9832 arraysize(kSOCKS5OkRequest)),
9833 MockWrite(
9834 "GET / HTTP/1.1\r\n"
9835 "Host: www.example.org\r\n"
9836 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359837
9838 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019839 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9840 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029841 MockRead("HTTP/1.0 200 OK\r\n"),
9842 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9843 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069844 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029845 };
9846
[email protected]31a2bfe2010-02-09 08:03:399847 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9848 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079849 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029850
[email protected]8ddf8322012-02-23 18:08:069851 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079852 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029853
[email protected]49639fa2011-12-20 23:22:419854 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029855
tfarina42834112016-09-22 13:38:209856 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029858
9859 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019860 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029861
bnc691fda62016-08-12 00:43:169862 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529863 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479864 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029865
[email protected]029c83b62013-01-24 05:28:209866 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169867 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209868 TestLoadTimingNotReusedWithPac(load_timing_info,
9869 CONNECT_TIMING_HAS_SSL_TIMES);
9870
[email protected]3cd17242009-06-23 02:59:029871 std::string response_text;
bnc691fda62016-08-12 00:43:169872 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019873 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029874 EXPECT_EQ("Payload", response_text);
9875}
9876
[email protected]448d4ca52012-03-04 04:12:239877namespace {
9878
[email protected]04e5be32009-06-26 20:00:319879// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069880
9881struct GroupNameTest {
9882 std::string proxy_server;
9883 std::string url;
9884 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189885 bool ssl;
[email protected]2d731a32010-04-29 01:04:069886};
9887
danakj1fd259a02016-04-16 03:17:099888std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079889 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099890 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069891
bnc525e175a2016-06-20 12:36:409892 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539893 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219894 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129895 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219896 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429897 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469898 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069899
9900 return session;
9901}
9902
mmenkee65e7af2015-10-13 17:16:429903int GroupNameTransactionHelper(const std::string& url,
9904 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069905 HttpRequestInfo request;
9906 request.method = "GET";
9907 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069908
bnc691fda62016-08-12 00:43:169909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279910
[email protected]49639fa2011-12-20 23:22:419911 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069912
9913 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209914 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069915}
9916
[email protected]448d4ca52012-03-04 04:12:239917} // namespace
9918
bncd16676a2016-07-20 16:23:019919TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069920 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239921 {
9922 "", // unused
9923 "http://www.example.org/direct",
9924 "www.example.org:80",
9925 false,
9926 },
9927 {
9928 "", // unused
9929 "http://[2001:1418:13:1::25]/direct",
9930 "[2001:1418:13:1::25]:80",
9931 false,
9932 },
[email protected]04e5be32009-06-26 20:00:319933
bncce36dca22015-04-21 22:11:239934 // SSL Tests
9935 {
9936 "", // unused
9937 "https://www.example.org/direct_ssl",
9938 "ssl/www.example.org:443",
9939 true,
9940 },
9941 {
9942 "", // unused
9943 "https://[2001:1418:13:1::25]/direct",
9944 "ssl/[2001:1418:13:1::25]:443",
9945 true,
9946 },
9947 {
9948 "", // unused
bncaa60ff402016-06-22 19:12:429949 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239950 "ssl/host.with.alternate:443",
9951 true,
9952 },
[email protected]2d731a32010-04-29 01:04:069953 };
[email protected]2ff8b312010-04-26 22:20:549954
viettrungluue4a8b882014-10-16 06:17:389955 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:599956 session_deps_.proxy_resolution_service =
9957 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099958 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409959 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069960
mmenkee65e7af2015-10-13 17:16:429961 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289962 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589963 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139964 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589965 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199966 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029967 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9968 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489969 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069970
9971 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429972 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:399973 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:189974 EXPECT_EQ(tests[i].expected_group_name,
9975 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:399976 } else {
[email protected]e60e47a2010-07-14 03:37:189977 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289978 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:399979 }
9980 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
9981 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
9982 // When SSL proxy is not in use, socket must be requested from
9983 // |transport_conn_pool|.
9984 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:069985 }
[email protected]2d731a32010-04-29 01:04:069986}
9987
bncd16676a2016-07-20 16:23:019988TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069989 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239990 {
Matt Menked1eb6d42018-01-17 04:54:069991 "http_proxy", "http://www.example.org/http_proxy_normal",
9992 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:239993 },
[email protected]2d731a32010-04-29 01:04:069994
bncce36dca22015-04-21 22:11:239995 // SSL Tests
9996 {
Matt Menked1eb6d42018-01-17 04:54:069997 "http_proxy", "https://www.example.org/http_connect_ssl",
9998 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:239999 },
[email protected]af3490e2010-10-16 21:02:2910000
bncce36dca22015-04-21 22:11:2310001 {
Matt Menked1eb6d42018-01-17 04:54:0610002 "http_proxy", "https://host.with.alternate/direct",
10003 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310004 },
[email protected]45499252013-01-23 17:12:5610005
bncce36dca22015-04-21 22:11:2310006 {
Matt Menked1eb6d42018-01-17 04:54:0610007 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10008 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310009 },
[email protected]2d731a32010-04-29 01:04:0610010 };
10011
viettrungluue4a8b882014-10-16 06:17:3810012 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910013 session_deps_.proxy_resolution_service =
10014 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910015 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010016 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610017
mmenkee65e7af2015-10-13 17:16:4210018 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610019
[email protected]e60e47a2010-07-14 03:37:1810020 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310021 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410022 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310023 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410024 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910025 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910026 mock_pool_manager->SetSocketPoolForHTTPProxy(
10027 proxy_host, base::WrapUnique(http_proxy_pool));
10028 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10029 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810030 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610031
10032 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210033 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810034 if (tests[i].ssl)
10035 EXPECT_EQ(tests[i].expected_group_name,
10036 ssl_conn_pool->last_group_name_received());
10037 else
10038 EXPECT_EQ(tests[i].expected_group_name,
10039 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610040 }
[email protected]2d731a32010-04-29 01:04:0610041}
10042
bncd16676a2016-07-20 16:23:0110043TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610044 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310045 {
10046 "socks4://socks_proxy:1080",
10047 "http://www.example.org/socks4_direct",
10048 "socks4/www.example.org:80",
10049 false,
10050 },
10051 {
10052 "socks5://socks_proxy:1080",
10053 "http://www.example.org/socks5_direct",
10054 "socks5/www.example.org:80",
10055 false,
10056 },
[email protected]2d731a32010-04-29 01:04:0610057
bncce36dca22015-04-21 22:11:2310058 // SSL Tests
10059 {
10060 "socks4://socks_proxy:1080",
10061 "https://www.example.org/socks4_ssl",
10062 "socks4/ssl/www.example.org:443",
10063 true,
10064 },
10065 {
10066 "socks5://socks_proxy:1080",
10067 "https://www.example.org/socks5_ssl",
10068 "socks5/ssl/www.example.org:443",
10069 true,
10070 },
[email protected]af3490e2010-10-16 21:02:2910071
bncce36dca22015-04-21 22:11:2310072 {
10073 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210074 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310075 "socks4/ssl/host.with.alternate:443",
10076 true,
10077 },
[email protected]04e5be32009-06-26 20:00:3110078 };
10079
viettrungluue4a8b882014-10-16 06:17:3810080 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910081 session_deps_.proxy_resolution_service =
10082 ProxyResolutionService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:0910083 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010084 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210085
mmenkee65e7af2015-10-13 17:16:4210086 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110087
[email protected]e60e47a2010-07-14 03:37:1810088 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310089 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410090 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310091 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410092 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910093 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910094 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10095 proxy_host, base::WrapUnique(socks_conn_pool));
10096 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10097 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810098 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110099
bnc691fda62016-08-12 00:43:1610100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110101
[email protected]2d731a32010-04-29 01:04:0610102 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210103 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810104 if (tests[i].ssl)
10105 EXPECT_EQ(tests[i].expected_group_name,
10106 ssl_conn_pool->last_group_name_received());
10107 else
10108 EXPECT_EQ(tests[i].expected_group_name,
10109 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110110 }
10111}
10112
bncd16676a2016-07-20 16:23:0110113TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710114 HttpRequestInfo request;
10115 request.method = "GET";
bncce36dca22015-04-21 22:11:2310116 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710117
Lily Houghton8c2f97d2018-01-22 05:06:5910118 session_deps_.proxy_resolution_service =
10119 ProxyResolutionService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:3210120
[email protected]69719062010-01-05 20:09:2110121 // This simulates failure resolving all hostnames; that means we will fail
10122 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710123 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210124
danakj1fd259a02016-04-16 03:17:0910125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510127
[email protected]49639fa2011-12-20 23:22:4110128 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510129
tfarina42834112016-09-22 13:38:2010130 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510132
[email protected]9172a982009-06-06 00:30:2510133 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110134 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510135}
10136
[email protected]685af592010-05-11 19:31:2410137// Base test to make sure that when the load flags for a request specify to
10138// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:0210139void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:0710140 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:2710141 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010142 HttpRequestInfo request_info;
10143 request_info.method = "GET";
10144 request_info.load_flags = load_flags;
10145 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:2710146
[email protected]a2c2fb92009-07-18 07:31:0410147 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910148 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210149
danakj1fd259a02016-04-16 03:17:0910150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810152
bncce36dca22015-04-21 22:11:2310153 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810154 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910155 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010156 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710157 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310158 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010159 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010160 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710162 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110163 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810164
10165 // Verify that it was added to host cache, by doing a subsequent async lookup
10166 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010167 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710168 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310169 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010170 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010171 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110172 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810173
bncce36dca22015-04-21 22:11:2310174 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810175 // we can tell if the next lookup hit the cache, or the "network".
10176 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310177 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810178
10179 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10180 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610181 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:3910182 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710183 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810184
[email protected]3b9cca42009-06-16 01:08:2810185 // Run the request.
tfarina42834112016-09-22 13:38:2010186 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110187 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110188 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810189
10190 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310191 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110192 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810193}
10194
[email protected]685af592010-05-11 19:31:2410195// There are multiple load flags that should trigger the host cache bypass.
10196// Test each in isolation:
bncd16676a2016-07-20 16:23:0110197TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:2410198 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
10199}
10200
bncd16676a2016-07-20 16:23:0110201TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:2410202 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
10203}
10204
bncd16676a2016-07-20 16:23:0110205TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:2410206 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
10207}
10208
[email protected]0877e3d2009-10-17 22:29:5710209// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110210TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710211 HttpRequestInfo request;
10212 request.method = "GET";
10213 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710214
10215 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610216 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710217 };
[email protected]31a2bfe2010-02-09 08:03:3910218 StaticSocketDataProvider data(NULL, 0,
10219 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:0710220 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910221 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710222
[email protected]49639fa2011-12-20 23:22:4110223 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710224
bnc691fda62016-08-12 00:43:1610225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710226
tfarina42834112016-09-22 13:38:2010227 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710229
10230 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110231 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910232
10233 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610234 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910235 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710236}
10237
zmo9528c9f42015-08-04 22:12:0810238// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110239TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710240 HttpRequestInfo request;
10241 request.method = "GET";
10242 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:5710243
10244 MockRead data_reads[] = {
10245 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610246 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710247 };
10248
[email protected]31a2bfe2010-02-09 08:03:3910249 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710250 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910251 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710252
[email protected]49639fa2011-12-20 23:22:4110253 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710254
bnc691fda62016-08-12 00:43:1610255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710256
tfarina42834112016-09-22 13:38:2010257 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110258 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710259
10260 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110261 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810262
bnc691fda62016-08-12 00:43:1610263 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210264 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810265
wezca1070932016-05-26 20:30:5210266 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810267 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10268
10269 std::string response_data;
bnc691fda62016-08-12 00:43:1610270 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110271 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810272 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910273
10274 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610275 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910276 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710277}
10278
10279// Make sure that a dropped connection while draining the body for auth
10280// restart does the right thing.
bncd16676a2016-07-20 16:23:0110281TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710282 HttpRequestInfo request;
10283 request.method = "GET";
bncce36dca22015-04-21 22:11:2310284 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710285
10286 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310287 MockWrite(
10288 "GET / HTTP/1.1\r\n"
10289 "Host: www.example.org\r\n"
10290 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710291 };
10292
10293 MockRead data_reads1[] = {
10294 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10295 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10296 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10297 MockRead("Content-Length: 14\r\n\r\n"),
10298 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610299 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710300 };
10301
[email protected]31a2bfe2010-02-09 08:03:3910302 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10303 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710304 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710305
bnc691fda62016-08-12 00:43:1610306 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710307 // be issuing -- the final header line contains the credentials.
10308 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310309 MockWrite(
10310 "GET / HTTP/1.1\r\n"
10311 "Host: www.example.org\r\n"
10312 "Connection: keep-alive\r\n"
10313 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710314 };
10315
10316 // Lastly, the server responds with the actual content.
10317 MockRead data_reads2[] = {
10318 MockRead("HTTP/1.1 200 OK\r\n"),
10319 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10320 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610321 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710322 };
10323
[email protected]31a2bfe2010-02-09 08:03:3910324 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10325 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:0710326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710328
[email protected]49639fa2011-12-20 23:22:4110329 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710330
bnc691fda62016-08-12 00:43:1610331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010332
tfarina42834112016-09-22 13:38:2010333 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710335
10336 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110337 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710338
bnc691fda62016-08-12 00:43:1610339 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210340 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410341 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710342
[email protected]49639fa2011-12-20 23:22:4110343 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710344
bnc691fda62016-08-12 00:43:1610345 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110346 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710347
10348 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110349 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710350
bnc691fda62016-08-12 00:43:1610351 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210352 ASSERT_TRUE(response);
10353 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710354 EXPECT_EQ(100, response->headers->GetContentLength());
10355}
10356
10357// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110358TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Lily Houghton8c2f97d2018-01-22 05:06:5910359 session_deps_.proxy_resolution_service =
10360 ProxyResolutionService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:5710361
10362 HttpRequestInfo request;
10363 request.method = "GET";
bncce36dca22015-04-21 22:11:2310364 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:5710365
10366 MockRead proxy_reads[] = {
10367 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610368 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710369 };
10370
[email protected]31a2bfe2010-02-09 08:03:3910371 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:0610372 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710373
[email protected]bb88e1d32013-05-03 23:11:0710374 session_deps_.socket_factory->AddSocketDataProvider(&data);
10375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710376
[email protected]49639fa2011-12-20 23:22:4110377 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710378
[email protected]bb88e1d32013-05-03 23:11:0710379 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710380
danakj1fd259a02016-04-16 03:17:0910381 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610382 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710383
tfarina42834112016-09-22 13:38:2010384 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710386
10387 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110388 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710389}
10390
bncd16676a2016-07-20 16:23:0110391TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610392 HttpRequestInfo request;
10393 request.method = "GET";
bncce36dca22015-04-21 22:11:2310394 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:4610395
danakj1fd259a02016-04-16 03:17:0910396 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610397 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710398
[email protected]e22e1362009-11-23 21:31:1210399 MockRead data_reads[] = {
10400 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610401 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210402 };
[email protected]9492e4a2010-02-24 00:58:4610403
10404 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710405 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610406
[email protected]49639fa2011-12-20 23:22:4110407 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610408
tfarina42834112016-09-22 13:38:2010409 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610411
robpercival214763f2016-07-01 23:27:0110412 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610413
bnc691fda62016-08-12 00:43:1610414 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210415 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610416
wezca1070932016-05-26 20:30:5210417 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610418 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10419
10420 std::string response_data;
bnc691fda62016-08-12 00:43:1610421 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110422 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210423}
10424
bncd16676a2016-07-20 16:23:0110425TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510426 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210427 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410428 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110429 UploadFileElementReader::ScopedOverridingContentLengthForTests
10430 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310431
danakj1fd259a02016-04-16 03:17:0910432 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910433 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410434 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710435 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210436 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710437
10438 HttpRequestInfo request;
10439 request.method = "POST";
bncce36dca22015-04-21 22:11:2310440 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710441 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710442
danakj1fd259a02016-04-16 03:17:0910443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310445
10446 MockRead data_reads[] = {
10447 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10448 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610449 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310450 };
[email protected]31a2bfe2010-02-09 08:03:3910451 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710452 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310453
[email protected]49639fa2011-12-20 23:22:4110454 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310455
tfarina42834112016-09-22 13:38:2010456 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310458
10459 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110460 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310461
bnc691fda62016-08-12 00:43:1610462 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210463 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310464
maksim.sisove869bf52016-06-23 17:11:5210465 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310466
[email protected]dd3aa792013-07-16 19:10:2310467 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310468}
10469
bncd16676a2016-07-20 16:23:0110470TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510471 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210472 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610473 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810474 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10475 base::WriteFile(temp_file, temp_file_content.c_str(),
10476 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110477 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610478
danakj1fd259a02016-04-16 03:17:0910479 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910480 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410481 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710482 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210483 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710484
10485 HttpRequestInfo request;
10486 request.method = "POST";
bncce36dca22015-04-21 22:11:2310487 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710488 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710489
[email protected]999dd8c2013-11-12 06:45:5410490 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910491 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610492 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610493
[email protected]999dd8c2013-11-12 06:45:5410494 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710495 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610496
[email protected]49639fa2011-12-20 23:22:4110497 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610498
tfarina42834112016-09-22 13:38:2010499 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610501
10502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110503 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610504
[email protected]dd3aa792013-07-16 19:10:2310505 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610506}
10507
bncd16676a2016-07-20 16:23:0110508TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310509 class FakeUploadElementReader : public UploadElementReader {
10510 public:
Chris Watkins7a41d3552017-12-01 02:13:2710511 FakeUploadElementReader() = default;
10512 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310513
Matt Menkecc1d3a902018-02-05 18:27:3310514 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310515
10516 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310517 int Init(CompletionOnceCallback callback) override {
10518 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310519 return ERR_IO_PENDING;
10520 }
avibf0746c2015-12-09 19:53:1410521 uint64_t GetContentLength() const override { return 0; }
10522 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010523 int Read(IOBuffer* buf,
10524 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310525 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310526 return ERR_FAILED;
10527 }
10528
10529 private:
Matt Menkecc1d3a902018-02-05 18:27:3310530 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310531 };
10532
10533 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910534 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10535 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210536 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310537
10538 HttpRequestInfo request;
10539 request.method = "POST";
bncce36dca22015-04-21 22:11:2310540 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310541 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:0310542
danakj1fd259a02016-04-16 03:17:0910543 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810544 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910545 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310546
10547 StaticSocketDataProvider data;
10548 session_deps_.socket_factory->AddSocketDataProvider(&data);
10549
10550 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010551 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510553 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310554
10555 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310556 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10557 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310558
10559 // Return Init()'s result after the transaction gets destroyed.
10560 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310561 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310562}
10563
[email protected]aeefc9e82010-02-19 16:18:2710564// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110565TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710566 HttpRequestInfo request;
10567 request.method = "GET";
bncce36dca22015-04-21 22:11:2310568 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710569
10570 // First transaction will request a resource and receive a Basic challenge
10571 // with realm="first_realm".
10572 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310573 MockWrite(
10574 "GET / HTTP/1.1\r\n"
10575 "Host: www.example.org\r\n"
10576 "Connection: keep-alive\r\n"
10577 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710578 };
10579 MockRead data_reads1[] = {
10580 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10581 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10582 "\r\n"),
10583 };
10584
bnc691fda62016-08-12 00:43:1610585 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710586 // for first_realm. The server will reject and provide a challenge with
10587 // second_realm.
10588 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310589 MockWrite(
10590 "GET / HTTP/1.1\r\n"
10591 "Host: www.example.org\r\n"
10592 "Connection: keep-alive\r\n"
10593 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10594 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710595 };
10596 MockRead data_reads2[] = {
10597 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10598 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10599 "\r\n"),
10600 };
10601
10602 // This again fails, and goes back to first_realm. Make sure that the
10603 // entry is removed from cache.
10604 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310605 MockWrite(
10606 "GET / HTTP/1.1\r\n"
10607 "Host: www.example.org\r\n"
10608 "Connection: keep-alive\r\n"
10609 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10610 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710611 };
10612 MockRead data_reads3[] = {
10613 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10614 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10615 "\r\n"),
10616 };
10617
10618 // Try one last time (with the correct password) and get the resource.
10619 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310620 MockWrite(
10621 "GET / HTTP/1.1\r\n"
10622 "Host: www.example.org\r\n"
10623 "Connection: keep-alive\r\n"
10624 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10625 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710626 };
10627 MockRead data_reads4[] = {
10628 MockRead("HTTP/1.1 200 OK\r\n"
10629 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010630 "Content-Length: 5\r\n"
10631 "\r\n"
10632 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710633 };
10634
10635 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10636 data_writes1, arraysize(data_writes1));
10637 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10638 data_writes2, arraysize(data_writes2));
10639 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10640 data_writes3, arraysize(data_writes3));
10641 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10642 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710643 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10644 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10645 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10646 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710647
[email protected]49639fa2011-12-20 23:22:4110648 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710649
danakj1fd259a02016-04-16 03:17:0910650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010652
[email protected]aeefc9e82010-02-19 16:18:2710653 // Issue the first request with Authorize headers. There should be a
10654 // password prompt for first_realm waiting to be filled in after the
10655 // transaction completes.
tfarina42834112016-09-22 13:38:2010656 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710658 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110659 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610660 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210661 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410662 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210663 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410664 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310665 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410666 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910667 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710668
10669 // Issue the second request with an incorrect password. There should be a
10670 // password prompt for second_realm waiting to be filled in after the
10671 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110672 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610673 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10674 callback2.callback());
robpercival214763f2016-07-01 23:27:0110675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710676 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110677 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610678 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210679 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410680 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210681 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410682 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310683 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410684 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910685 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710686
10687 // Issue the third request with another incorrect password. There should be
10688 // a password prompt for first_realm waiting to be filled in. If the password
10689 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10690 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110691 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610692 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10693 callback3.callback());
robpercival214763f2016-07-01 23:27:0110694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710695 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110696 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610697 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210698 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410699 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210700 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410701 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310702 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410703 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910704 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710705
10706 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110707 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610708 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10709 callback4.callback());
robpercival214763f2016-07-01 23:27:0110710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710711 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110712 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610713 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210714 ASSERT_TRUE(response);
10715 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710716}
10717
Bence Béky230ac612017-08-30 19:17:0810718// Regression test for https://crbug.com/754395.
10719TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10720 MockRead data_reads[] = {
10721 MockRead("HTTP/1.1 200 OK\r\n"),
10722 MockRead(kAlternativeServiceHttpHeader),
10723 MockRead("\r\n"),
10724 MockRead("hello world"),
10725 MockRead(SYNCHRONOUS, OK),
10726 };
10727
10728 HttpRequestInfo request;
10729 request.method = "GET";
10730 request.url = GURL("https://www.example.org/");
10731
10732 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10733 session_deps_.socket_factory->AddSocketDataProvider(&data);
10734
10735 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910736 ssl.ssl_info.cert =
10737 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10738 ASSERT_TRUE(ssl.ssl_info.cert);
10739 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0810740 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10741
10742 TestCompletionCallback callback;
10743
10744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10746
10747 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10749
10750 url::SchemeHostPort test_server(request.url);
10751 HttpServerProperties* http_server_properties =
10752 session->http_server_properties();
10753 EXPECT_TRUE(
10754 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10755
10756 EXPECT_THAT(callback.WaitForResult(), IsOk());
10757
10758 const HttpResponseInfo* response = trans.GetResponseInfo();
10759 ASSERT_TRUE(response);
10760 ASSERT_TRUE(response->headers);
10761 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10762 EXPECT_FALSE(response->was_fetched_via_spdy);
10763 EXPECT_FALSE(response->was_alpn_negotiated);
10764
10765 std::string response_data;
10766 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10767 EXPECT_EQ("hello world", response_data);
10768
10769 EXPECT_TRUE(
10770 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10771}
10772
bncd16676a2016-07-20 16:23:0110773TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210774 MockRead data_reads[] = {
10775 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310776 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210777 MockRead("\r\n"),
10778 MockRead("hello world"),
10779 MockRead(SYNCHRONOUS, OK),
10780 };
10781
10782 HttpRequestInfo request;
10783 request.method = "GET";
bncb26024382016-06-29 02:39:4510784 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210785
10786 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210787 session_deps_.socket_factory->AddSocketDataProvider(&data);
10788
bncb26024382016-06-29 02:39:4510789 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910790 ssl.ssl_info.cert =
10791 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10792 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10794
bncc958faa2015-07-31 18:14:5210795 TestCompletionCallback callback;
10796
danakj1fd259a02016-04-16 03:17:0910797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210799
tfarina42834112016-09-22 13:38:2010800 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210802
bncb26024382016-06-29 02:39:4510803 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010804 HttpServerProperties* http_server_properties =
10805 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410806 EXPECT_TRUE(
10807 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210808
robpercival214763f2016-07-01 23:27:0110809 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210810
bnc691fda62016-08-12 00:43:1610811 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210812 ASSERT_TRUE(response);
10813 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210814 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10815 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210816 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210817
10818 std::string response_data;
bnc691fda62016-08-12 00:43:1610819 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210820 EXPECT_EQ("hello world", response_data);
10821
zhongyic4de03032017-05-19 04:07:3410822 AlternativeServiceInfoVector alternative_service_info_vector =
10823 http_server_properties->GetAlternativeServiceInfos(test_server);
10824 ASSERT_EQ(1u, alternative_service_info_vector.size());
10825 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10826 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410827 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210828}
10829
bnce3dd56f2016-06-01 10:37:1110830// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110831TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110832 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110833 MockRead data_reads[] = {
10834 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310835 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110836 MockRead("\r\n"),
10837 MockRead("hello world"),
10838 MockRead(SYNCHRONOUS, OK),
10839 };
10840
10841 HttpRequestInfo request;
10842 request.method = "GET";
10843 request.url = GURL("http://www.example.org/");
10844 request.load_flags = 0;
10845
10846 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10847 session_deps_.socket_factory->AddSocketDataProvider(&data);
10848
10849 TestCompletionCallback callback;
10850
10851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110853
10854 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010855 HttpServerProperties* http_server_properties =
10856 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410857 EXPECT_TRUE(
10858 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110859
tfarina42834112016-09-22 13:38:2010860 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10862 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110863
bnc691fda62016-08-12 00:43:1610864 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110865 ASSERT_TRUE(response);
10866 ASSERT_TRUE(response->headers);
10867 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10868 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210869 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110870
10871 std::string response_data;
bnc691fda62016-08-12 00:43:1610872 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110873 EXPECT_EQ("hello world", response_data);
10874
zhongyic4de03032017-05-19 04:07:3410875 EXPECT_TRUE(
10876 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110877}
10878
bnca86731e2017-04-17 12:31:2810879// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510880// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110881TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510882 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810883 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510884
bnc8bef8da22016-05-30 01:28:2510885 HttpRequestInfo request;
10886 request.method = "GET";
bncb26024382016-06-29 02:39:4510887 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510888 request.load_flags = 0;
10889
10890 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10891 StaticSocketDataProvider first_data;
10892 first_data.set_connect_data(mock_connect);
10893 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510894 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610895 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510896 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510897
10898 MockRead data_reads[] = {
10899 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10900 MockRead(ASYNC, OK),
10901 };
10902 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10903 0);
10904 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10905
10906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10907
bnc525e175a2016-06-20 12:36:4010908 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510909 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110910 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10911 444);
bnc8bef8da22016-05-30 01:28:2510912 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110913 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510914 url::SchemeHostPort(request.url), alternative_service, expiration);
10915
bnc691fda62016-08-12 00:43:1610916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510917 TestCompletionCallback callback;
10918
tfarina42834112016-09-22 13:38:2010919 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510920 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110921 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510922}
10923
bnce3dd56f2016-06-01 10:37:1110924// Regression test for https://crbug.com/615497:
10925// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110926TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110927 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110928 HttpRequestInfo request;
10929 request.method = "GET";
10930 request.url = GURL("http://www.example.org/");
10931 request.load_flags = 0;
10932
10933 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10934 StaticSocketDataProvider first_data;
10935 first_data.set_connect_data(mock_connect);
10936 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10937
10938 MockRead data_reads[] = {
10939 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10940 MockRead(ASYNC, OK),
10941 };
10942 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10943 0);
10944 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10945
10946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10947
bnc525e175a2016-06-20 12:36:4010948 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110949 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110950 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110951 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110952 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110953 url::SchemeHostPort(request.url), alternative_service, expiration);
10954
bnc691fda62016-08-12 00:43:1610955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110956 TestCompletionCallback callback;
10957
tfarina42834112016-09-22 13:38:2010958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110959 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110960 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110961}
10962
bncd16676a2016-07-20 16:23:0110963TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810964 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910965 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010966 HttpServerProperties* http_server_properties =
10967 session->http_server_properties();
bncb26024382016-06-29 02:39:4510968 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110969 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810970 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110971 http_server_properties->SetQuicAlternativeService(
10972 test_server, alternative_service, expiration,
10973 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410974 EXPECT_EQ(
10975 1u,
10976 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810977
10978 // Send a clear header.
10979 MockRead data_reads[] = {
10980 MockRead("HTTP/1.1 200 OK\r\n"),
10981 MockRead("Alt-Svc: clear\r\n"),
10982 MockRead("\r\n"),
10983 MockRead("hello world"),
10984 MockRead(SYNCHRONOUS, OK),
10985 };
10986 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10987 session_deps_.socket_factory->AddSocketDataProvider(&data);
10988
bncb26024382016-06-29 02:39:4510989 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910990 ssl.ssl_info.cert =
10991 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10992 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10994
bnc4f575852015-10-14 18:35:0810995 HttpRequestInfo request;
10996 request.method = "GET";
bncb26024382016-06-29 02:39:4510997 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810998
10999 TestCompletionCallback callback;
11000
bnc691fda62016-08-12 00:43:1611001 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811002
tfarina42834112016-09-22 13:38:2011003 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111004 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811005
bnc691fda62016-08-12 00:43:1611006 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211007 ASSERT_TRUE(response);
11008 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811009 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11010 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211011 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811012
11013 std::string response_data;
bnc691fda62016-08-12 00:43:1611014 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811015 EXPECT_EQ("hello world", response_data);
11016
zhongyic4de03032017-05-19 04:07:3411017 EXPECT_TRUE(
11018 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811019}
11020
bncd16676a2016-07-20 16:23:0111021TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211022 MockRead data_reads[] = {
11023 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311024 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11025 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211026 MockRead("hello world"),
11027 MockRead(SYNCHRONOUS, OK),
11028 };
11029
11030 HttpRequestInfo request;
11031 request.method = "GET";
bncb26024382016-06-29 02:39:4511032 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5211033
11034 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211035 session_deps_.socket_factory->AddSocketDataProvider(&data);
11036
bncb26024382016-06-29 02:39:4511037 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911038 ssl.ssl_info.cert =
11039 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11040 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511041 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11042
bncc958faa2015-07-31 18:14:5211043 TestCompletionCallback callback;
11044
danakj1fd259a02016-04-16 03:17:0911045 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211047
tfarina42834112016-09-22 13:38:2011048 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211050
bncb26024382016-06-29 02:39:4511051 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011052 HttpServerProperties* http_server_properties =
11053 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411054 EXPECT_TRUE(
11055 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211056
robpercival214763f2016-07-01 23:27:0111057 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211058
bnc691fda62016-08-12 00:43:1611059 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211060 ASSERT_TRUE(response);
11061 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211062 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11063 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211064 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211065
11066 std::string response_data;
bnc691fda62016-08-12 00:43:1611067 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211068 EXPECT_EQ("hello world", response_data);
11069
zhongyic4de03032017-05-19 04:07:3411070 AlternativeServiceInfoVector alternative_service_info_vector =
11071 http_server_properties->GetAlternativeServiceInfos(test_server);
11072 ASSERT_EQ(2u, alternative_service_info_vector.size());
11073
11074 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11075 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411076 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411077 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11078 1234);
11079 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411080 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211081}
11082
bncd16676a2016-07-20 16:23:0111083TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611084 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211085 HostPortPair alternative("alternative.example.org", 443);
11086 std::string origin_url = "https://origin.example.org:443";
11087 std::string alternative_url = "https://alternative.example.org:443";
11088
11089 // Negotiate HTTP/1.1 with alternative.example.org.
11090 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611091 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211092 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11093
11094 // HTTP/1.1 data for request.
11095 MockWrite http_writes[] = {
11096 MockWrite("GET / HTTP/1.1\r\n"
11097 "Host: alternative.example.org\r\n"
11098 "Connection: keep-alive\r\n\r\n"),
11099 };
11100
11101 MockRead http_reads[] = {
11102 MockRead("HTTP/1.1 200 OK\r\n"
11103 "Content-Type: text/html; charset=iso-8859-1\r\n"
11104 "Content-Length: 40\r\n\r\n"
11105 "first HTTP/1.1 response from alternative"),
11106 };
11107 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11108 http_writes, arraysize(http_writes));
11109 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11110
11111 StaticSocketDataProvider data_refused;
11112 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11113 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11114
zhongyi3d4a55e72016-04-22 20:36:4611115 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911116 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011117 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211118 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111119 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211120 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111121 http_server_properties->SetQuicAlternativeService(
11122 server, alternative_service, expiration,
11123 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211124 // Mark the QUIC alternative service as broken.
11125 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11126
zhongyi48704c182015-12-07 07:52:0211127 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211129 request.method = "GET";
11130 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211131 TestCompletionCallback callback;
11132 NetErrorDetails details;
11133 EXPECT_FALSE(details.quic_broken);
11134
tfarina42834112016-09-22 13:38:2011135 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611136 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211137 EXPECT_TRUE(details.quic_broken);
11138}
11139
bncd16676a2016-07-20 16:23:0111140TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611141 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211142 HostPortPair alternative1("alternative1.example.org", 443);
11143 HostPortPair alternative2("alternative2.example.org", 443);
11144 std::string origin_url = "https://origin.example.org:443";
11145 std::string alternative_url1 = "https://alternative1.example.org:443";
11146 std::string alternative_url2 = "https://alternative2.example.org:443";
11147
11148 // Negotiate HTTP/1.1 with alternative1.example.org.
11149 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611150 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11152
11153 // HTTP/1.1 data for request.
11154 MockWrite http_writes[] = {
11155 MockWrite("GET / HTTP/1.1\r\n"
11156 "Host: alternative1.example.org\r\n"
11157 "Connection: keep-alive\r\n\r\n"),
11158 };
11159
11160 MockRead http_reads[] = {
11161 MockRead("HTTP/1.1 200 OK\r\n"
11162 "Content-Type: text/html; charset=iso-8859-1\r\n"
11163 "Content-Length: 40\r\n\r\n"
11164 "first HTTP/1.1 response from alternative1"),
11165 };
11166 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11167 http_writes, arraysize(http_writes));
11168 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11169
11170 StaticSocketDataProvider data_refused;
11171 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11172 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11173
danakj1fd259a02016-04-16 03:17:0911174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011175 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211176 session->http_server_properties();
11177
zhongyi3d4a55e72016-04-22 20:36:4611178 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211179 AlternativeServiceInfoVector alternative_service_info_vector;
11180 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11181
bnc3472afd2016-11-17 15:27:2111182 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111183 alternative_service_info_vector.push_back(
11184 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11185 alternative_service1, expiration,
11186 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111187 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111188 alternative_service_info_vector.push_back(
11189 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11190 alternative_service2, expiration,
11191 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211192
11193 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611194 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211195
11196 // Mark one of the QUIC alternative service as broken.
11197 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411198 EXPECT_EQ(2u,
11199 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211200
zhongyi48704c182015-12-07 07:52:0211201 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211203 request.method = "GET";
11204 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211205 TestCompletionCallback callback;
11206 NetErrorDetails details;
11207 EXPECT_FALSE(details.quic_broken);
11208
tfarina42834112016-09-22 13:38:2011209 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611210 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211211 EXPECT_FALSE(details.quic_broken);
11212}
11213
bncd16676a2016-07-20 16:23:0111214TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211215 HttpRequestInfo request;
11216 request.method = "GET";
bncb26024382016-06-29 02:39:4511217 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4211218
[email protected]d973e99a2012-02-17 21:02:3611219 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211220 StaticSocketDataProvider first_data;
11221 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711222 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511223 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611224 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211226
11227 MockRead data_reads[] = {
11228 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11229 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611230 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211231 };
11232 StaticSocketDataProvider second_data(
11233 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711234 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211235
danakj1fd259a02016-04-16 03:17:0911236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211237
bnc525e175a2016-06-20 12:36:4011238 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311239 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611240 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111241 // Port must be < 1024, or the header will be ignored (since initial port was
11242 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111243 // Port is ignored by MockConnect anyway.
11244 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11245 666);
bnc7dc7e1b42015-07-28 14:43:1211246 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111247 http_server_properties->SetHttp2AlternativeService(
11248 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211249
bnc691fda62016-08-12 00:43:1611250 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111251 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211252
tfarina42834112016-09-22 13:38:2011253 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11255 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211256
bnc691fda62016-08-12 00:43:1611257 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211258 ASSERT_TRUE(response);
11259 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211260 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11261
11262 std::string response_data;
bnc691fda62016-08-12 00:43:1611263 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211264 EXPECT_EQ("hello world", response_data);
11265
zhongyic4de03032017-05-19 04:07:3411266 const AlternativeServiceInfoVector alternative_service_info_vector =
11267 http_server_properties->GetAlternativeServiceInfos(server);
11268 ASSERT_EQ(1u, alternative_service_info_vector.size());
11269 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411270 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411271 EXPECT_TRUE(
11272 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211273}
11274
bnc55ff9da2015-08-19 18:42:3511275// Ensure that we are not allowed to redirect traffic via an alternate protocol
11276// to an unrestricted (port >= 1024) when the original traffic was on a
11277// restricted port (port < 1024). Ensure that we can redirect in all other
11278// cases.
bncd16676a2016-07-20 16:23:0111279TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111280 HttpRequestInfo restricted_port_request;
11281 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511282 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111283 restricted_port_request.load_flags = 0;
11284
[email protected]d973e99a2012-02-17 21:02:3611285 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111286 StaticSocketDataProvider first_data;
11287 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711288 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111289
11290 MockRead data_reads[] = {
11291 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11292 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611293 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111294 };
11295 StaticSocketDataProvider second_data(
11296 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711297 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511298 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611299 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511300 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111301
danakj1fd259a02016-04-16 03:17:0911302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111303
bnc525e175a2016-06-20 12:36:4011304 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311305 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111306 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111307 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11308 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211309 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111310 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611311 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011312 expiration);
[email protected]3912662a32011-10-04 00:51:1111313
bnc691fda62016-08-12 00:43:1611314 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111315 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111316
tfarina42834112016-09-22 13:38:2011317 int rv = trans.Start(&restricted_port_request, callback.callback(),
11318 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111320 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111321 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911322}
[email protected]3912662a32011-10-04 00:51:1111323
bnc55ff9da2015-08-19 18:42:3511324// Ensure that we are allowed to redirect traffic via an alternate protocol to
11325// an unrestricted (port >= 1024) when the original traffic was on a restricted
11326// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111327TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711328 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911329
11330 HttpRequestInfo restricted_port_request;
11331 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511332 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911333 restricted_port_request.load_flags = 0;
11334
11335 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11336 StaticSocketDataProvider first_data;
11337 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711338 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911339
11340 MockRead data_reads[] = {
11341 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11342 MockRead("hello world"),
11343 MockRead(ASYNC, OK),
11344 };
11345 StaticSocketDataProvider second_data(
11346 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711347 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511348 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611349 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511350 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911351
danakj1fd259a02016-04-16 03:17:0911352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911353
bnc525e175a2016-06-20 12:36:4011354 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911355 session->http_server_properties();
11356 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111357 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11358 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211359 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111360 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611361 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011362 expiration);
[email protected]c54c6962013-02-01 04:53:1911363
bnc691fda62016-08-12 00:43:1611364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911365 TestCompletionCallback callback;
11366
tfarina42834112016-09-22 13:38:2011367 EXPECT_EQ(ERR_IO_PENDING,
11368 trans.Start(&restricted_port_request, callback.callback(),
11369 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911370 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111371 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111372}
11373
bnc55ff9da2015-08-19 18:42:3511374// Ensure that we are not allowed to redirect traffic via an alternate protocol
11375// to an unrestricted (port >= 1024) when the original traffic was on a
11376// restricted port (port < 1024). Ensure that we can redirect in all other
11377// cases.
bncd16676a2016-07-20 16:23:0111378TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111379 HttpRequestInfo restricted_port_request;
11380 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511381 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111382 restricted_port_request.load_flags = 0;
11383
[email protected]d973e99a2012-02-17 21:02:3611384 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111385 StaticSocketDataProvider first_data;
11386 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711387 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111388
11389 MockRead data_reads[] = {
11390 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11391 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611392 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111393 };
11394 StaticSocketDataProvider second_data(
11395 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711396 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111397
bncb26024382016-06-29 02:39:4511398 SSLSocketDataProvider ssl(ASYNC, OK);
11399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11400
danakj1fd259a02016-04-16 03:17:0911401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111402
bnc525e175a2016-06-20 12:36:4011403 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311404 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111405 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111406 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11407 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211408 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111409 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611410 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011411 expiration);
[email protected]3912662a32011-10-04 00:51:1111412
bnc691fda62016-08-12 00:43:1611413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111414 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111415
tfarina42834112016-09-22 13:38:2011416 int rv = trans.Start(&restricted_port_request, callback.callback(),
11417 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111419 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111420 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111421}
11422
bnc55ff9da2015-08-19 18:42:3511423// Ensure that we are not allowed to redirect traffic via an alternate protocol
11424// to an unrestricted (port >= 1024) when the original traffic was on a
11425// restricted port (port < 1024). Ensure that we can redirect in all other
11426// cases.
bncd16676a2016-07-20 16:23:0111427TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111428 HttpRequestInfo unrestricted_port_request;
11429 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511430 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111431 unrestricted_port_request.load_flags = 0;
11432
[email protected]d973e99a2012-02-17 21:02:3611433 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111434 StaticSocketDataProvider first_data;
11435 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711436 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111437
11438 MockRead data_reads[] = {
11439 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11440 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611441 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111442 };
11443 StaticSocketDataProvider second_data(
11444 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711445 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511446 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611447 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111449
danakj1fd259a02016-04-16 03:17:0911450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111451
bnc525e175a2016-06-20 12:36:4011452 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311453 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111454 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111455 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11456 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211457 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111458 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611459 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011460 expiration);
[email protected]3912662a32011-10-04 00:51:1111461
bnc691fda62016-08-12 00:43:1611462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111463 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111464
bnc691fda62016-08-12 00:43:1611465 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011466 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111468 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111469 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111470}
11471
bnc55ff9da2015-08-19 18:42:3511472// Ensure that we are not allowed to redirect traffic via an alternate protocol
11473// to an unrestricted (port >= 1024) when the original traffic was on a
11474// restricted port (port < 1024). Ensure that we can redirect in all other
11475// cases.
bncd16676a2016-07-20 16:23:0111476TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111477 HttpRequestInfo unrestricted_port_request;
11478 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511479 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111480 unrestricted_port_request.load_flags = 0;
11481
[email protected]d973e99a2012-02-17 21:02:3611482 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111483 StaticSocketDataProvider first_data;
11484 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711485 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111486
11487 MockRead data_reads[] = {
11488 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11489 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611490 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111491 };
11492 StaticSocketDataProvider second_data(
11493 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711494 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111495
bncb26024382016-06-29 02:39:4511496 SSLSocketDataProvider ssl(ASYNC, OK);
11497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11498
danakj1fd259a02016-04-16 03:17:0911499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111500
bnc525e175a2016-06-20 12:36:4011501 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311502 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211503 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111504 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11505 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211506 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111507 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611508 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011509 expiration);
[email protected]3912662a32011-10-04 00:51:1111510
bnc691fda62016-08-12 00:43:1611511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111512 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111513
bnc691fda62016-08-12 00:43:1611514 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011515 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111517 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111518 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111519}
11520
bnc55ff9da2015-08-19 18:42:3511521// Ensure that we are not allowed to redirect traffic via an alternate protocol
11522// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11523// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111524TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211525 HttpRequestInfo request;
11526 request.method = "GET";
bncce36dca22015-04-21 22:11:2311527 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211528
11529 // The alternate protocol request will error out before we attempt to connect,
11530 // so only the standard HTTP request will try to connect.
11531 MockRead data_reads[] = {
11532 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11533 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611534 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211535 };
11536 StaticSocketDataProvider data(
11537 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711538 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211539
danakj1fd259a02016-04-16 03:17:0911540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211541
bnc525e175a2016-06-20 12:36:4011542 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211543 session->http_server_properties();
11544 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111545 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11546 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211547 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111548 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611549 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211550
bnc691fda62016-08-12 00:43:1611551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211552 TestCompletionCallback callback;
11553
tfarina42834112016-09-22 13:38:2011554 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211556 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111557 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211558
bnc691fda62016-08-12 00:43:1611559 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211560 ASSERT_TRUE(response);
11561 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211562 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11563
11564 std::string response_data;
bnc691fda62016-08-12 00:43:1611565 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211566 EXPECT_EQ("hello world", response_data);
11567}
11568
bncd16676a2016-07-20 16:23:0111569TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411570 HttpRequestInfo request;
11571 request.method = "GET";
bncb26024382016-06-29 02:39:4511572 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411573
11574 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211575 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311576 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211577 MockRead("\r\n"),
11578 MockRead("hello world"),
11579 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11580 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411581
11582 StaticSocketDataProvider first_transaction(
11583 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711584 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511585 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611586 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411588
bnc032658ba2016-09-26 18:17:1511589 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411590
bncdf80d44fd2016-07-15 20:27:4111591 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511592 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111593 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411594
bnc42331402016-07-25 13:36:1511595 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111596 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411597 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111598 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411599 };
11600
rch8e6c6c42015-05-01 14:05:1311601 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11602 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711603 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411604
[email protected]d973e99a2012-02-17 21:02:3611605 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511606 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11607 NULL, 0, NULL, 0);
11608 hanging_non_alternate_protocol_socket.set_connect_data(
11609 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711610 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511611 &hanging_non_alternate_protocol_socket);
11612
[email protected]49639fa2011-12-20 23:22:4111613 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411614
danakj1fd259a02016-04-16 03:17:0911615 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811616 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911617 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411618
tfarina42834112016-09-22 13:38:2011619 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111620 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11621 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411622
11623 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211624 ASSERT_TRUE(response);
11625 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11627
11628 std::string response_data;
robpercival214763f2016-07-01 23:27:0111629 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411630 EXPECT_EQ("hello world", response_data);
11631
bnc87dcefc2017-05-25 12:47:5811632 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911633 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411634
tfarina42834112016-09-22 13:38:2011635 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11637 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411638
11639 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211640 ASSERT_TRUE(response);
11641 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211642 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311643 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211644 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411645
robpercival214763f2016-07-01 23:27:0111646 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411647 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411648}
11649
bncd16676a2016-07-20 16:23:0111650TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511651 HttpRequestInfo request;
11652 request.method = "GET";
bncb26024382016-06-29 02:39:4511653 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511654
bncb26024382016-06-29 02:39:4511655 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511656 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211657 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311658 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211659 MockRead("\r\n"),
11660 MockRead("hello world"),
11661 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11662 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511663 };
11664
bncb26024382016-06-29 02:39:4511665 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11666 0);
11667 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511668
bncb26024382016-06-29 02:39:4511669 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911670 ssl_http11.ssl_info.cert =
11671 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11672 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511673 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11674
11675 // Second transaction starts an alternative and a non-alternative Job.
11676 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611677 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811678 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11679 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811680 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11681
11682 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11683 hanging_socket2.set_connect_data(never_finishing_connect);
11684 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511685
bncb26024382016-06-29 02:39:4511686 // Third transaction starts an alternative and a non-alternative job.
11687 // The non-alternative job hangs, but the alternative one succeeds.
11688 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111689 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511690 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111691 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511692 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511693 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111694 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511695 };
bnc42331402016-07-25 13:36:1511696 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111697 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511698 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111699 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511700 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111701 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11702 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311703 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511704 };
11705
rch8e6c6c42015-05-01 14:05:1311706 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11707 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711708 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511709
bnc032658ba2016-09-26 18:17:1511710 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511711
mmenkecc2298e2015-12-07 18:20:1811712 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11713 hanging_socket3.set_connect_data(never_finishing_connect);
11714 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511715
danakj1fd259a02016-04-16 03:17:0911716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111717 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011718 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511719
tfarina42834112016-09-22 13:38:2011720 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11722 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511723
11724 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211725 ASSERT_TRUE(response);
11726 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511727 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11728
11729 std::string response_data;
robpercival214763f2016-07-01 23:27:0111730 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511731 EXPECT_EQ("hello world", response_data);
11732
[email protected]49639fa2011-12-20 23:22:4111733 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011734 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011735 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511737
[email protected]49639fa2011-12-20 23:22:4111738 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011739 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011740 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511742
robpercival214763f2016-07-01 23:27:0111743 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11744 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511745
11746 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211747 ASSERT_TRUE(response);
11748 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211749 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511750 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211751 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111752 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511753 EXPECT_EQ("hello!", response_data);
11754
11755 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211756 ASSERT_TRUE(response);
11757 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211758 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511759 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211760 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111761 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511762 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511763}
11764
bncd16676a2016-07-20 16:23:0111765TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511766 HttpRequestInfo request;
11767 request.method = "GET";
bncb26024382016-06-29 02:39:4511768 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511769
11770 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211771 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311772 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211773 MockRead("\r\n"),
11774 MockRead("hello world"),
11775 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11776 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511777 };
11778
11779 StaticSocketDataProvider first_transaction(
11780 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711781 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511782
[email protected]8ddf8322012-02-23 18:08:0611783 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911784 ssl.ssl_info.cert =
11785 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11786 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0711787 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511788
[email protected]d973e99a2012-02-17 21:02:3611789 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511790 StaticSocketDataProvider hanging_alternate_protocol_socket(
11791 NULL, 0, NULL, 0);
11792 hanging_alternate_protocol_socket.set_connect_data(
11793 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711794 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511795 &hanging_alternate_protocol_socket);
11796
bncb26024382016-06-29 02:39:4511797 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811798 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11799 NULL, 0);
11800 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511802
[email protected]49639fa2011-12-20 23:22:4111803 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511804
danakj1fd259a02016-04-16 03:17:0911805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811806 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911807 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511808
tfarina42834112016-09-22 13:38:2011809 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11811 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511812
11813 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211814 ASSERT_TRUE(response);
11815 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511816 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11817
11818 std::string response_data;
robpercival214763f2016-07-01 23:27:0111819 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511820 EXPECT_EQ("hello world", response_data);
11821
bnc87dcefc2017-05-25 12:47:5811822 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911823 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511824
tfarina42834112016-09-22 13:38:2011825 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11827 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511828
11829 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211830 ASSERT_TRUE(response);
11831 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511832 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11833 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211834 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511835
robpercival214763f2016-07-01 23:27:0111836 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511837 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511838}
11839
[email protected]631f1322010-04-30 17:59:1111840class CapturingProxyResolver : public ProxyResolver {
11841 public:
Chris Watkins7a41d3552017-12-01 02:13:2711842 CapturingProxyResolver() = default;
11843 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1111844
dchengb03027d2014-10-21 12:00:2011845 int GetProxyForURL(const GURL& url,
11846 ProxyInfo* results,
11847 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511848 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011849 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011850 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11851 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211852 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111853 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211854 return OK;
[email protected]631f1322010-04-30 17:59:1111855 }
11856
[email protected]24476402010-07-20 20:55:1711857 const std::vector<GURL>& resolved() const { return resolved_; }
11858
11859 private:
[email protected]631f1322010-04-30 17:59:1111860 std::vector<GURL> resolved_;
11861
11862 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11863};
11864
sammce64b2362015-04-29 03:50:2311865class CapturingProxyResolverFactory : public ProxyResolverFactory {
11866 public:
11867 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11868 : ProxyResolverFactory(false), resolver_(resolver) {}
11869
11870 int CreateProxyResolver(
11871 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911872 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311873 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911874 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911875 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311876 return OK;
11877 }
11878
11879 private:
11880 ProxyResolver* resolver_;
11881};
11882
bnc2e884782016-08-11 19:45:1911883// Test that proxy is resolved using the origin url,
11884// regardless of the alternative server.
11885TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11886 // Configure proxy to bypass www.example.org, which is the origin URL.
11887 ProxyConfig proxy_config;
11888 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11889 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11890 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911891 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911892
11893 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911894 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911895 &capturing_proxy_resolver);
11896
11897 TestNetLog net_log;
11898
Lily Houghton8c2f97d2018-01-22 05:06:5911899 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1911900 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11901 &net_log);
11902
11903 session_deps_.net_log = &net_log;
11904
11905 // Configure alternative service with a hostname that is not bypassed by the
11906 // proxy.
11907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11908 HttpServerProperties* http_server_properties =
11909 session->http_server_properties();
11910 url::SchemeHostPort server("https", "www.example.org", 443);
11911 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111912 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911913 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111914 http_server_properties->SetHttp2AlternativeService(
11915 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911916
11917 // Non-alternative job should hang.
11918 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11919 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11920 nullptr, 0);
11921 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11922 session_deps_.socket_factory->AddSocketDataProvider(
11923 &hanging_alternate_protocol_socket);
11924
bnc032658ba2016-09-26 18:17:1511925 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911926
11927 HttpRequestInfo request;
11928 request.method = "GET";
11929 request.url = GURL("https://www.example.org/");
11930 request.load_flags = 0;
11931
11932 SpdySerializedFrame req(
11933 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11934
11935 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11936
11937 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11938 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11939 MockRead spdy_reads[] = {
11940 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11941 };
11942
11943 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11944 arraysize(spdy_writes));
11945 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11946
11947 TestCompletionCallback callback;
11948
11949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11950
tfarina42834112016-09-22 13:38:2011951 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911952 EXPECT_THAT(callback.GetResult(rv), IsOk());
11953
11954 const HttpResponseInfo* response = trans.GetResponseInfo();
11955 ASSERT_TRUE(response);
11956 ASSERT_TRUE(response->headers);
11957 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11958 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211959 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911960
11961 std::string response_data;
11962 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11963 EXPECT_EQ("hello!", response_data);
11964
11965 // Origin host bypasses proxy, no resolution should have happened.
11966 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11967}
11968
bncd16676a2016-07-20 16:23:0111969TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111970 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211971 proxy_config.set_auto_detect(true);
11972 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111973
sammc5dd160c2015-04-02 02:43:1311974 CapturingProxyResolver capturing_proxy_resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5911975 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1911976 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11977 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811978 &capturing_proxy_resolver),
11979 nullptr);
vishal.b62985ca92015-04-17 08:45:5111980 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711981 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111982
11983 HttpRequestInfo request;
11984 request.method = "GET";
bncb26024382016-06-29 02:39:4511985 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111986
11987 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211988 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311989 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211990 MockRead("\r\n"),
11991 MockRead("hello world"),
11992 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11993 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111994 };
11995
11996 StaticSocketDataProvider first_transaction(
11997 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711998 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511999 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612000 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112002
bnc032658ba2016-09-26 18:17:1512003 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112004
bncdf80d44fd2016-07-15 20:27:4112005 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512006 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112007 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312008 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512009 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12010 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312011 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112012 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112013 };
12014
[email protected]d911f1b2010-05-05 22:39:4212015 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12016
bnc42331402016-07-25 13:36:1512017 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112018 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112019 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112020 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12021 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112022 };
12023
rch8e6c6c42015-05-01 14:05:1312024 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12025 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712026 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112027
[email protected]d973e99a2012-02-17 21:02:3612028 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512029 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12030 NULL, 0, NULL, 0);
12031 hanging_non_alternate_protocol_socket.set_connect_data(
12032 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712033 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512034 &hanging_non_alternate_protocol_socket);
12035
[email protected]49639fa2011-12-20 23:22:4112036 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112037
danakj1fd259a02016-04-16 03:17:0912038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812039 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912040 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112041
tfarina42834112016-09-22 13:38:2012042 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12044 EXPECT_THAT(callback.WaitForResult(), IsOk());
12045
12046 const HttpResponseInfo* response = trans->GetResponseInfo();
12047 ASSERT_TRUE(response);
12048 ASSERT_TRUE(response->headers);
12049 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12050 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212051 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112052
12053 std::string response_data;
12054 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12055 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112056
bnc87dcefc2017-05-25 12:47:5812057 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912058 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112059
tfarina42834112016-09-22 13:38:2012060 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12062 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112063
mmenkea2dcd3bf2016-08-16 21:49:4112064 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212065 ASSERT_TRUE(response);
12066 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212067 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312068 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212069 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112070
robpercival214763f2016-07-01 23:27:0112071 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112072 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512073 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12074 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312075 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312076 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312077 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112078
[email protected]029c83b62013-01-24 05:28:2012079 LoadTimingInfo load_timing_info;
12080 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12081 TestLoadTimingNotReusedWithPac(load_timing_info,
12082 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112083}
[email protected]631f1322010-04-30 17:59:1112084
bncd16676a2016-07-20 16:23:0112085TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812086 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412087 HttpRequestInfo request;
12088 request.method = "GET";
bncb26024382016-06-29 02:39:4512089 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5412090
12091 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212092 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312093 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212094 MockRead("\r\n"),
12095 MockRead("hello world"),
12096 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412097 };
12098
12099 StaticSocketDataProvider first_transaction(
12100 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712101 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512102 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612103 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512104 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412105
bnc032658ba2016-09-26 18:17:1512106 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412107
bncdf80d44fd2016-07-15 20:27:4112108 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512109 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112110 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412111
bnc42331402016-07-25 13:36:1512112 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112113 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412114 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112115 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412116 };
12117
rch8e6c6c42015-05-01 14:05:1312118 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12119 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712120 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412121
[email protected]83039bb2011-12-09 18:43:5512122 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412123
danakj1fd259a02016-04-16 03:17:0912124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412125
bnc87dcefc2017-05-25 12:47:5812126 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912127 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412128
tfarina42834112016-09-22 13:38:2012129 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12131 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412132
12133 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212134 ASSERT_TRUE(response);
12135 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412136 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12137
12138 std::string response_data;
robpercival214763f2016-07-01 23:27:0112139 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412140 EXPECT_EQ("hello world", response_data);
12141
12142 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512143 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012144 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412145 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712146 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212147 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812148
bnc87dcefc2017-05-25 12:47:5812149 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912150 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412151
tfarina42834112016-09-22 13:38:2012152 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12154 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412155
12156 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212157 ASSERT_TRUE(response);
12158 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212159 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312160 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212161 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412162
robpercival214763f2016-07-01 23:27:0112163 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412164 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212165}
12166
[email protected]044de0642010-06-17 10:42:1512167// GenerateAuthToken is a mighty big test.
12168// It tests all permutation of GenerateAuthToken behavior:
12169// - Synchronous and Asynchronous completion.
12170// - OK or error on completion.
12171// - Direct connection, non-authenticating proxy, and authenticating proxy.
12172// - HTTP or HTTPS backend (to include proxy tunneling).
12173// - Non-authenticating and authenticating backend.
12174//
[email protected]fe3b7dc2012-02-03 19:52:0912175// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512176// problems generating an auth token for an authenticating proxy, we don't
12177// need to test all permutations of the backend server).
12178//
12179// The test proceeds by going over each of the configuration cases, and
12180// potentially running up to three rounds in each of the tests. The TestConfig
12181// specifies both the configuration for the test as well as the expectations
12182// for the results.
bncd16676a2016-07-20 16:23:0112183TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012184 static const char kServer[] = "http://www.example.com";
12185 static const char kSecureServer[] = "https://www.example.com";
12186 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512187
12188 enum AuthTiming {
12189 AUTH_NONE,
12190 AUTH_SYNC,
12191 AUTH_ASYNC,
12192 };
12193
12194 const MockWrite kGet(
12195 "GET / HTTP/1.1\r\n"
12196 "Host: www.example.com\r\n"
12197 "Connection: keep-alive\r\n\r\n");
12198 const MockWrite kGetProxy(
12199 "GET http://www.example.com/ HTTP/1.1\r\n"
12200 "Host: www.example.com\r\n"
12201 "Proxy-Connection: keep-alive\r\n\r\n");
12202 const MockWrite kGetAuth(
12203 "GET / HTTP/1.1\r\n"
12204 "Host: www.example.com\r\n"
12205 "Connection: keep-alive\r\n"
12206 "Authorization: auth_token\r\n\r\n");
12207 const MockWrite kGetProxyAuth(
12208 "GET http://www.example.com/ HTTP/1.1\r\n"
12209 "Host: www.example.com\r\n"
12210 "Proxy-Connection: keep-alive\r\n"
12211 "Proxy-Authorization: auth_token\r\n\r\n");
12212 const MockWrite kGetAuthThroughProxy(
12213 "GET http://www.example.com/ HTTP/1.1\r\n"
12214 "Host: www.example.com\r\n"
12215 "Proxy-Connection: keep-alive\r\n"
12216 "Authorization: auth_token\r\n\r\n");
12217 const MockWrite kGetAuthWithProxyAuth(
12218 "GET http://www.example.com/ HTTP/1.1\r\n"
12219 "Host: www.example.com\r\n"
12220 "Proxy-Connection: keep-alive\r\n"
12221 "Proxy-Authorization: auth_token\r\n"
12222 "Authorization: auth_token\r\n\r\n");
12223 const MockWrite kConnect(
12224 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712225 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512226 "Proxy-Connection: keep-alive\r\n\r\n");
12227 const MockWrite kConnectProxyAuth(
12228 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712229 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512230 "Proxy-Connection: keep-alive\r\n"
12231 "Proxy-Authorization: auth_token\r\n\r\n");
12232
12233 const MockRead kSuccess(
12234 "HTTP/1.1 200 OK\r\n"
12235 "Content-Type: text/html; charset=iso-8859-1\r\n"
12236 "Content-Length: 3\r\n\r\n"
12237 "Yes");
12238 const MockRead kFailure(
12239 "Should not be called.");
12240 const MockRead kServerChallenge(
12241 "HTTP/1.1 401 Unauthorized\r\n"
12242 "WWW-Authenticate: Mock realm=server\r\n"
12243 "Content-Type: text/html; charset=iso-8859-1\r\n"
12244 "Content-Length: 14\r\n\r\n"
12245 "Unauthorized\r\n");
12246 const MockRead kProxyChallenge(
12247 "HTTP/1.1 407 Unauthorized\r\n"
12248 "Proxy-Authenticate: Mock realm=proxy\r\n"
12249 "Proxy-Connection: close\r\n"
12250 "Content-Type: text/html; charset=iso-8859-1\r\n"
12251 "Content-Length: 14\r\n\r\n"
12252 "Unauthorized\r\n");
12253 const MockRead kProxyConnected(
12254 "HTTP/1.1 200 Connection Established\r\n\r\n");
12255
12256 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12257 // no constructors, but the C++ compiler on Windows warns about
12258 // unspecified data in compound literals. So, moved to using constructors,
12259 // and TestRound's created with the default constructor should not be used.
12260 struct TestRound {
12261 TestRound()
12262 : expected_rv(ERR_UNEXPECTED),
12263 extra_write(NULL),
12264 extra_read(NULL) {
12265 }
12266 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12267 int expected_rv_arg)
12268 : write(write_arg),
12269 read(read_arg),
12270 expected_rv(expected_rv_arg),
12271 extra_write(NULL),
12272 extra_read(NULL) {
12273 }
12274 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12275 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112276 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512277 : write(write_arg),
12278 read(read_arg),
12279 expected_rv(expected_rv_arg),
12280 extra_write(extra_write_arg),
12281 extra_read(extra_read_arg) {
12282 }
12283 MockWrite write;
12284 MockRead read;
12285 int expected_rv;
12286 const MockWrite* extra_write;
12287 const MockRead* extra_read;
12288 };
12289
12290 static const int kNoSSL = 500;
12291
12292 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112293 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112294 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512295 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112296 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112297 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512298 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112299 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512300 int num_auth_rounds;
12301 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612302 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512303 } test_configs[] = {
asankac93076192016-10-03 15:46:0212304 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112305 {__LINE__,
12306 nullptr,
asankac93076192016-10-03 15:46:0212307 AUTH_NONE,
12308 OK,
12309 kServer,
12310 AUTH_NONE,
12311 OK,
12312 1,
12313 kNoSSL,
12314 {TestRound(kGet, kSuccess, OK)}},
12315 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112316 {__LINE__,
12317 nullptr,
asankac93076192016-10-03 15:46:0212318 AUTH_NONE,
12319 OK,
12320 kServer,
12321 AUTH_SYNC,
12322 OK,
12323 2,
12324 kNoSSL,
12325 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512326 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112327 {__LINE__,
12328 nullptr,
asankac93076192016-10-03 15:46:0212329 AUTH_NONE,
12330 OK,
12331 kServer,
12332 AUTH_SYNC,
12333 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612334 3,
12335 kNoSSL,
12336 {TestRound(kGet, kServerChallenge, OK),
12337 TestRound(kGet, kServerChallenge, OK),
12338 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112339 {__LINE__,
12340 nullptr,
asankae2257db2016-10-11 22:03:1612341 AUTH_NONE,
12342 OK,
12343 kServer,
12344 AUTH_SYNC,
12345 ERR_UNSUPPORTED_AUTH_SCHEME,
12346 2,
12347 kNoSSL,
12348 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112349 {__LINE__,
12350 nullptr,
asankae2257db2016-10-11 22:03:1612351 AUTH_NONE,
12352 OK,
12353 kServer,
12354 AUTH_SYNC,
12355 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12356 2,
12357 kNoSSL,
12358 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112359 {__LINE__,
12360 kProxy,
asankae2257db2016-10-11 22:03:1612361 AUTH_SYNC,
12362 ERR_FAILED,
12363 kServer,
12364 AUTH_NONE,
12365 OK,
12366 2,
12367 kNoSSL,
12368 {TestRound(kGetProxy, kProxyChallenge, OK),
12369 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112370 {__LINE__,
12371 kProxy,
asankae2257db2016-10-11 22:03:1612372 AUTH_ASYNC,
12373 ERR_FAILED,
12374 kServer,
12375 AUTH_NONE,
12376 OK,
12377 2,
12378 kNoSSL,
12379 {TestRound(kGetProxy, kProxyChallenge, OK),
12380 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112381 {__LINE__,
12382 nullptr,
asankae2257db2016-10-11 22:03:1612383 AUTH_NONE,
12384 OK,
12385 kServer,
12386 AUTH_SYNC,
12387 ERR_FAILED,
asankac93076192016-10-03 15:46:0212388 2,
12389 kNoSSL,
12390 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612391 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112392 {__LINE__,
12393 nullptr,
asankae2257db2016-10-11 22:03:1612394 AUTH_NONE,
12395 OK,
12396 kServer,
12397 AUTH_ASYNC,
12398 ERR_FAILED,
12399 2,
12400 kNoSSL,
12401 {TestRound(kGet, kServerChallenge, OK),
12402 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112403 {__LINE__,
12404 nullptr,
asankac93076192016-10-03 15:46:0212405 AUTH_NONE,
12406 OK,
12407 kServer,
12408 AUTH_ASYNC,
12409 OK,
12410 2,
12411 kNoSSL,
12412 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512413 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112414 {__LINE__,
12415 nullptr,
asankac93076192016-10-03 15:46:0212416 AUTH_NONE,
12417 OK,
12418 kServer,
12419 AUTH_ASYNC,
12420 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612421 3,
asankac93076192016-10-03 15:46:0212422 kNoSSL,
12423 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612424 // The second round uses a HttpAuthHandlerMock that always succeeds.
12425 TestRound(kGet, kServerChallenge, OK),
12426 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212427 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112428 {__LINE__,
12429 kProxy,
asankac93076192016-10-03 15:46:0212430 AUTH_NONE,
12431 OK,
12432 kServer,
12433 AUTH_NONE,
12434 OK,
12435 1,
12436 kNoSSL,
12437 {TestRound(kGetProxy, kSuccess, OK)}},
12438 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112439 {__LINE__,
12440 kProxy,
asankac93076192016-10-03 15:46:0212441 AUTH_NONE,
12442 OK,
12443 kServer,
12444 AUTH_SYNC,
12445 OK,
12446 2,
12447 kNoSSL,
12448 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512449 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112450 {__LINE__,
12451 kProxy,
asankac93076192016-10-03 15:46:0212452 AUTH_NONE,
12453 OK,
12454 kServer,
12455 AUTH_SYNC,
12456 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612457 3,
asankac93076192016-10-03 15:46:0212458 kNoSSL,
12459 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612460 TestRound(kGetProxy, kServerChallenge, OK),
12461 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112462 {__LINE__,
12463 kProxy,
asankac93076192016-10-03 15:46:0212464 AUTH_NONE,
12465 OK,
12466 kServer,
12467 AUTH_ASYNC,
12468 OK,
12469 2,
12470 kNoSSL,
12471 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512472 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112473 {__LINE__,
12474 kProxy,
asankac93076192016-10-03 15:46:0212475 AUTH_NONE,
12476 OK,
12477 kServer,
12478 AUTH_ASYNC,
12479 ERR_INVALID_AUTH_CREDENTIALS,
12480 2,
12481 kNoSSL,
12482 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612483 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212484 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112485 {__LINE__,
12486 kProxy,
asankac93076192016-10-03 15:46:0212487 AUTH_SYNC,
12488 OK,
12489 kServer,
12490 AUTH_NONE,
12491 OK,
12492 2,
12493 kNoSSL,
12494 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512495 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112496 {__LINE__,
12497 kProxy,
asankac93076192016-10-03 15:46:0212498 AUTH_SYNC,
12499 ERR_INVALID_AUTH_CREDENTIALS,
12500 kServer,
12501 AUTH_NONE,
12502 OK,
12503 2,
12504 kNoSSL,
12505 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612506 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112507 {__LINE__,
12508 kProxy,
asankac93076192016-10-03 15:46:0212509 AUTH_ASYNC,
12510 OK,
12511 kServer,
12512 AUTH_NONE,
12513 OK,
12514 2,
12515 kNoSSL,
12516 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512517 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112518 {__LINE__,
12519 kProxy,
asankac93076192016-10-03 15:46:0212520 AUTH_ASYNC,
12521 ERR_INVALID_AUTH_CREDENTIALS,
12522 kServer,
12523 AUTH_NONE,
12524 OK,
12525 2,
12526 kNoSSL,
12527 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612528 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112529 {__LINE__,
12530 kProxy,
12531 AUTH_ASYNC,
12532 ERR_INVALID_AUTH_CREDENTIALS,
12533 kServer,
12534 AUTH_NONE,
12535 OK,
12536 3,
12537 kNoSSL,
12538 {TestRound(kGetProxy, kProxyChallenge, OK),
12539 TestRound(kGetProxy, kProxyChallenge, OK),
12540 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212541 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112542 {__LINE__,
12543 kProxy,
asankac93076192016-10-03 15:46:0212544 AUTH_SYNC,
12545 OK,
12546 kServer,
12547 AUTH_SYNC,
12548 OK,
12549 3,
12550 kNoSSL,
12551 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512552 TestRound(kGetProxyAuth, kServerChallenge, OK),
12553 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112554 {__LINE__,
12555 kProxy,
asankac93076192016-10-03 15:46:0212556 AUTH_SYNC,
12557 OK,
12558 kServer,
12559 AUTH_SYNC,
12560 ERR_INVALID_AUTH_CREDENTIALS,
12561 3,
12562 kNoSSL,
12563 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512564 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612565 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112566 {__LINE__,
12567 kProxy,
asankac93076192016-10-03 15:46:0212568 AUTH_ASYNC,
12569 OK,
12570 kServer,
12571 AUTH_SYNC,
12572 OK,
12573 3,
12574 kNoSSL,
12575 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512576 TestRound(kGetProxyAuth, kServerChallenge, OK),
12577 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112578 {__LINE__,
12579 kProxy,
asankac93076192016-10-03 15:46:0212580 AUTH_ASYNC,
12581 OK,
12582 kServer,
12583 AUTH_SYNC,
12584 ERR_INVALID_AUTH_CREDENTIALS,
12585 3,
12586 kNoSSL,
12587 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512588 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612589 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112590 {__LINE__,
12591 kProxy,
asankac93076192016-10-03 15:46:0212592 AUTH_SYNC,
12593 OK,
12594 kServer,
12595 AUTH_ASYNC,
12596 OK,
12597 3,
12598 kNoSSL,
12599 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512600 TestRound(kGetProxyAuth, kServerChallenge, OK),
12601 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112602 {__LINE__,
12603 kProxy,
12604 AUTH_SYNC,
12605 ERR_INVALID_AUTH_CREDENTIALS,
12606 kServer,
12607 AUTH_ASYNC,
12608 OK,
12609 4,
12610 kNoSSL,
12611 {TestRound(kGetProxy, kProxyChallenge, OK),
12612 TestRound(kGetProxy, kProxyChallenge, OK),
12613 TestRound(kGetProxyAuth, kServerChallenge, OK),
12614 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12615 {__LINE__,
12616 kProxy,
asankac93076192016-10-03 15:46:0212617 AUTH_SYNC,
12618 OK,
12619 kServer,
12620 AUTH_ASYNC,
12621 ERR_INVALID_AUTH_CREDENTIALS,
12622 3,
12623 kNoSSL,
12624 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512625 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612626 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112627 {__LINE__,
12628 kProxy,
asankac93076192016-10-03 15:46:0212629 AUTH_ASYNC,
12630 OK,
12631 kServer,
12632 AUTH_ASYNC,
12633 OK,
12634 3,
12635 kNoSSL,
12636 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512637 TestRound(kGetProxyAuth, kServerChallenge, OK),
12638 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112639 {__LINE__,
12640 kProxy,
asankac93076192016-10-03 15:46:0212641 AUTH_ASYNC,
12642 OK,
12643 kServer,
12644 AUTH_ASYNC,
12645 ERR_INVALID_AUTH_CREDENTIALS,
12646 3,
12647 kNoSSL,
12648 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512649 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612650 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112651 {__LINE__,
12652 kProxy,
12653 AUTH_ASYNC,
12654 ERR_INVALID_AUTH_CREDENTIALS,
12655 kServer,
12656 AUTH_ASYNC,
12657 ERR_INVALID_AUTH_CREDENTIALS,
12658 4,
12659 kNoSSL,
12660 {TestRound(kGetProxy, kProxyChallenge, OK),
12661 TestRound(kGetProxy, kProxyChallenge, OK),
12662 TestRound(kGetProxyAuth, kServerChallenge, OK),
12663 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212664 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112665 {__LINE__,
12666 nullptr,
asankac93076192016-10-03 15:46:0212667 AUTH_NONE,
12668 OK,
12669 kSecureServer,
12670 AUTH_NONE,
12671 OK,
12672 1,
12673 0,
12674 {TestRound(kGet, kSuccess, OK)}},
12675 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112676 {__LINE__,
12677 nullptr,
asankac93076192016-10-03 15:46:0212678 AUTH_NONE,
12679 OK,
12680 kSecureServer,
12681 AUTH_SYNC,
12682 OK,
12683 2,
12684 0,
12685 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512686 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112687 {__LINE__,
12688 nullptr,
asankac93076192016-10-03 15:46:0212689 AUTH_NONE,
12690 OK,
12691 kSecureServer,
12692 AUTH_SYNC,
12693 ERR_INVALID_AUTH_CREDENTIALS,
12694 2,
12695 0,
asankae2257db2016-10-11 22:03:1612696 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112697 {__LINE__,
12698 nullptr,
asankac93076192016-10-03 15:46:0212699 AUTH_NONE,
12700 OK,
12701 kSecureServer,
12702 AUTH_ASYNC,
12703 OK,
12704 2,
12705 0,
12706 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512707 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112708 {__LINE__,
12709 nullptr,
asankac93076192016-10-03 15:46:0212710 AUTH_NONE,
12711 OK,
12712 kSecureServer,
12713 AUTH_ASYNC,
12714 ERR_INVALID_AUTH_CREDENTIALS,
12715 2,
12716 0,
asankae2257db2016-10-11 22:03:1612717 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212718 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112719 {__LINE__,
12720 kProxy,
asankac93076192016-10-03 15:46:0212721 AUTH_NONE,
12722 OK,
12723 kSecureServer,
12724 AUTH_NONE,
12725 OK,
12726 1,
12727 0,
12728 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12729 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112730 {__LINE__,
12731 kProxy,
asankac93076192016-10-03 15:46:0212732 AUTH_NONE,
12733 OK,
12734 kSecureServer,
12735 AUTH_SYNC,
12736 OK,
12737 2,
12738 0,
12739 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512740 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112741 {__LINE__,
12742 kProxy,
asankac93076192016-10-03 15:46:0212743 AUTH_NONE,
12744 OK,
12745 kSecureServer,
12746 AUTH_SYNC,
12747 ERR_INVALID_AUTH_CREDENTIALS,
12748 2,
12749 0,
12750 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612751 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112752 {__LINE__,
12753 kProxy,
asankac93076192016-10-03 15:46:0212754 AUTH_NONE,
12755 OK,
12756 kSecureServer,
12757 AUTH_ASYNC,
12758 OK,
12759 2,
12760 0,
12761 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512762 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112763 {__LINE__,
12764 kProxy,
asankac93076192016-10-03 15:46:0212765 AUTH_NONE,
12766 OK,
12767 kSecureServer,
12768 AUTH_ASYNC,
12769 ERR_INVALID_AUTH_CREDENTIALS,
12770 2,
12771 0,
12772 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612773 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212774 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112775 {__LINE__,
12776 kProxy,
asankac93076192016-10-03 15:46:0212777 AUTH_SYNC,
12778 OK,
12779 kSecureServer,
12780 AUTH_NONE,
12781 OK,
12782 2,
12783 1,
12784 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512785 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112786 {__LINE__,
12787 kProxy,
asankac93076192016-10-03 15:46:0212788 AUTH_SYNC,
12789 ERR_INVALID_AUTH_CREDENTIALS,
12790 kSecureServer,
12791 AUTH_NONE,
12792 OK,
12793 2,
12794 kNoSSL,
12795 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612796 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112797 {__LINE__,
12798 kProxy,
asankae2257db2016-10-11 22:03:1612799 AUTH_SYNC,
12800 ERR_UNSUPPORTED_AUTH_SCHEME,
12801 kSecureServer,
12802 AUTH_NONE,
12803 OK,
12804 2,
12805 kNoSSL,
12806 {TestRound(kConnect, kProxyChallenge, OK),
12807 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112808 {__LINE__,
12809 kProxy,
asankae2257db2016-10-11 22:03:1612810 AUTH_SYNC,
12811 ERR_UNEXPECTED,
12812 kSecureServer,
12813 AUTH_NONE,
12814 OK,
12815 2,
12816 kNoSSL,
12817 {TestRound(kConnect, kProxyChallenge, OK),
12818 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112819 {__LINE__,
12820 kProxy,
asankac93076192016-10-03 15:46:0212821 AUTH_ASYNC,
12822 OK,
12823 kSecureServer,
12824 AUTH_NONE,
12825 OK,
12826 2,
12827 1,
12828 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512829 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112830 {__LINE__,
12831 kProxy,
asankac93076192016-10-03 15:46:0212832 AUTH_ASYNC,
12833 ERR_INVALID_AUTH_CREDENTIALS,
12834 kSecureServer,
12835 AUTH_NONE,
12836 OK,
12837 2,
12838 kNoSSL,
12839 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612840 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212841 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112842 {__LINE__,
12843 kProxy,
asankac93076192016-10-03 15:46:0212844 AUTH_SYNC,
12845 OK,
12846 kSecureServer,
12847 AUTH_SYNC,
12848 OK,
12849 3,
12850 1,
12851 {TestRound(kConnect, kProxyChallenge, OK),
12852 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12853 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512854 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112855 {__LINE__,
12856 kProxy,
asankac93076192016-10-03 15:46:0212857 AUTH_SYNC,
12858 OK,
12859 kSecureServer,
12860 AUTH_SYNC,
12861 ERR_INVALID_AUTH_CREDENTIALS,
12862 3,
12863 1,
12864 {TestRound(kConnect, kProxyChallenge, OK),
12865 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12866 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612867 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112868 {__LINE__,
12869 kProxy,
asankac93076192016-10-03 15:46:0212870 AUTH_ASYNC,
12871 OK,
12872 kSecureServer,
12873 AUTH_SYNC,
12874 OK,
12875 3,
12876 1,
12877 {TestRound(kConnect, kProxyChallenge, OK),
12878 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12879 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512880 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112881 {__LINE__,
12882 kProxy,
asankac93076192016-10-03 15:46:0212883 AUTH_ASYNC,
12884 OK,
12885 kSecureServer,
12886 AUTH_SYNC,
12887 ERR_INVALID_AUTH_CREDENTIALS,
12888 3,
12889 1,
12890 {TestRound(kConnect, kProxyChallenge, OK),
12891 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12892 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612893 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112894 {__LINE__,
12895 kProxy,
asankac93076192016-10-03 15:46:0212896 AUTH_SYNC,
12897 OK,
12898 kSecureServer,
12899 AUTH_ASYNC,
12900 OK,
12901 3,
12902 1,
12903 {TestRound(kConnect, kProxyChallenge, OK),
12904 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12905 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512906 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112907 {__LINE__,
12908 kProxy,
asankac93076192016-10-03 15:46:0212909 AUTH_SYNC,
12910 OK,
12911 kSecureServer,
12912 AUTH_ASYNC,
12913 ERR_INVALID_AUTH_CREDENTIALS,
12914 3,
12915 1,
12916 {TestRound(kConnect, kProxyChallenge, OK),
12917 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12918 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612919 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112920 {__LINE__,
12921 kProxy,
asankac93076192016-10-03 15:46:0212922 AUTH_ASYNC,
12923 OK,
12924 kSecureServer,
12925 AUTH_ASYNC,
12926 OK,
12927 3,
12928 1,
12929 {TestRound(kConnect, kProxyChallenge, OK),
12930 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12931 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512932 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112933 {__LINE__,
12934 kProxy,
asankac93076192016-10-03 15:46:0212935 AUTH_ASYNC,
12936 OK,
12937 kSecureServer,
12938 AUTH_ASYNC,
12939 ERR_INVALID_AUTH_CREDENTIALS,
12940 3,
12941 1,
12942 {TestRound(kConnect, kProxyChallenge, OK),
12943 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12944 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612945 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112946 {__LINE__,
12947 kProxy,
12948 AUTH_ASYNC,
12949 ERR_INVALID_AUTH_CREDENTIALS,
12950 kSecureServer,
12951 AUTH_ASYNC,
12952 ERR_INVALID_AUTH_CREDENTIALS,
12953 4,
12954 2,
12955 {TestRound(kConnect, kProxyChallenge, OK),
12956 TestRound(kConnect, kProxyChallenge, OK),
12957 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12958 &kServerChallenge),
12959 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512960 };
12961
asanka463ca4262016-11-16 02:34:3112962 for (const auto& test_config : test_configs) {
12963 SCOPED_TRACE(::testing::Message() << "Test config at "
12964 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812965 HttpAuthHandlerMock::Factory* auth_factory(
12966 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712967 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912968 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612969
12970 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512971 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112972 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812973 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12974 std::string auth_challenge = "Mock realm=proxy";
12975 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412976 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12977 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812978 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012979 empty_ssl_info, origin,
12980 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812981 auth_handler->SetGenerateExpectation(
12982 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112983 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812984 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12985 }
[email protected]044de0642010-06-17 10:42:1512986 }
12987 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012988 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512989 std::string auth_challenge = "Mock realm=server";
12990 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412991 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12992 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512993 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012994 empty_ssl_info, origin,
12995 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512996 auth_handler->SetGenerateExpectation(
12997 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112998 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812999 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613000
13001 // The second handler always succeeds. It should only be used where there
13002 // are multiple auth sessions for server auth in the same network
13003 // transaction using the same auth scheme.
13004 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913005 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613006 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13007 empty_ssl_info, origin,
13008 NetLogWithSource());
13009 second_handler->SetGenerateExpectation(true, OK);
13010 auth_factory->AddMockHandler(second_handler.release(),
13011 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513012 }
13013 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913014 session_deps_.proxy_resolution_service =
13015 ProxyResolutionService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1513016 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913017 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513018 }
13019
13020 HttpRequestInfo request;
13021 request.method = "GET";
13022 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1513023
danakj1fd259a02016-04-16 03:17:0913024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513025
rchcb68dc62015-05-21 04:45:3613026 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13027
13028 std::vector<std::vector<MockRead>> mock_reads(1);
13029 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513030 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213031 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513032 const TestRound& read_write_round = test_config.rounds[round];
13033
13034 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613035 mock_reads.back().push_back(read_write_round.read);
13036 mock_writes.back().push_back(read_write_round.write);
13037
13038 // kProxyChallenge uses Proxy-Connection: close which means that the
13039 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413040 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613041 mock_reads.push_back(std::vector<MockRead>());
13042 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513043 }
13044
rchcb68dc62015-05-21 04:45:3613045 if (read_write_round.extra_read) {
13046 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513047 }
rchcb68dc62015-05-21 04:45:3613048 if (read_write_round.extra_write) {
13049 mock_writes.back().push_back(*read_write_round.extra_write);
13050 }
[email protected]044de0642010-06-17 10:42:1513051
13052 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513053 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713054 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513055 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613056 }
[email protected]044de0642010-06-17 10:42:1513057
danakj1fd259a02016-04-16 03:17:0913058 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613059 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913060 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413061 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813062 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613063 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213064 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613065 }
13066
mmenkecc2298e2015-12-07 18:20:1813067 // Transaction must be created after DataProviders, so it's destroyed before
13068 // they are as well.
13069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13070
rchcb68dc62015-05-21 04:45:3613071 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213072 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613073 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513074 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113075 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513076 int rv;
13077 if (round == 0) {
tfarina42834112016-09-22 13:38:2013078 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513079 } else {
[email protected]49639fa2011-12-20 23:22:4113080 rv = trans.RestartWithAuth(
13081 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513082 }
13083 if (rv == ERR_IO_PENDING)
13084 rv = callback.WaitForResult();
13085
13086 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613087 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013088 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513089 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513090 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13091 continue;
13092 }
13093 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213094 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513095 } else {
wezca1070932016-05-26 20:30:5213096 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613097 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513098 }
13099 }
[email protected]e5ae96a2010-04-14 20:12:4513100 }
13101}
13102
bncd16676a2016-07-20 16:23:0113103TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413104 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413105 HttpAuthHandlerMock::Factory* auth_factory(
13106 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713107 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913108 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713109 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13110 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413111
13112 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13113 auth_handler->set_connection_based(true);
13114 std::string auth_challenge = "Mock realm=server";
13115 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413116 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13117 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913118 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413119 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013120 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813121 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413122
[email protected]c871bce92010-07-15 21:51:1413123 int rv = OK;
13124 const HttpResponseInfo* response = NULL;
13125 HttpRequestInfo request;
13126 request.method = "GET";
13127 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2713128
danakj1fd259a02016-04-16 03:17:0913129 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013130
13131 // Use a TCP Socket Pool with only one connection per group. This is used
13132 // to validate that the TCP socket is not released to the pool between
13133 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213134 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813135 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013136 50, // Max sockets for pool
13137 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113138 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13139 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913140 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213141 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813142 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013143
bnc691fda62016-08-12 00:43:1613144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113145 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413146
13147 const MockWrite kGet(
13148 "GET / HTTP/1.1\r\n"
13149 "Host: www.example.com\r\n"
13150 "Connection: keep-alive\r\n\r\n");
13151 const MockWrite kGetAuth(
13152 "GET / HTTP/1.1\r\n"
13153 "Host: www.example.com\r\n"
13154 "Connection: keep-alive\r\n"
13155 "Authorization: auth_token\r\n\r\n");
13156
13157 const MockRead kServerChallenge(
13158 "HTTP/1.1 401 Unauthorized\r\n"
13159 "WWW-Authenticate: Mock realm=server\r\n"
13160 "Content-Type: text/html; charset=iso-8859-1\r\n"
13161 "Content-Length: 14\r\n\r\n"
13162 "Unauthorized\r\n");
13163 const MockRead kSuccess(
13164 "HTTP/1.1 200 OK\r\n"
13165 "Content-Type: text/html; charset=iso-8859-1\r\n"
13166 "Content-Length: 3\r\n\r\n"
13167 "Yes");
13168
13169 MockWrite writes[] = {
13170 // First round
13171 kGet,
13172 // Second round
13173 kGetAuth,
13174 // Third round
13175 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013176 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013177 kGetAuth,
13178 // Competing request
13179 kGet,
[email protected]c871bce92010-07-15 21:51:1413180 };
13181 MockRead reads[] = {
13182 // First round
13183 kServerChallenge,
13184 // Second round
13185 kServerChallenge,
13186 // Third round
[email protected]eca50e122010-09-11 14:03:3013187 kServerChallenge,
13188 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413189 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013190 // Competing response
13191 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413192 };
13193 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13194 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713195 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413196
thestig9d3bb0c2015-01-24 00:49:5113197 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013198
13199 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413200 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013201 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413202 if (rv == ERR_IO_PENDING)
13203 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113204 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613205 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213206 ASSERT_TRUE(response);
13207 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813208 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113209 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13210 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413211
[email protected]7ef4cbbb2011-02-06 11:19:1013212 // In between rounds, another request comes in for the same domain.
13213 // It should not be able to grab the TCP socket that trans has already
13214 // claimed.
bnc691fda62016-08-12 00:43:1613215 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113216 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013217 rv = trans_compete.Start(&request, callback_compete.callback(),
13218 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013220 // callback_compete.WaitForResult at this point would stall forever,
13221 // since the HttpNetworkTransaction does not release the request back to
13222 // the pool until after authentication completes.
13223
13224 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413225 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613226 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413227 if (rv == ERR_IO_PENDING)
13228 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113229 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613230 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213231 ASSERT_TRUE(response);
13232 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813233 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113234 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13235 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413236
[email protected]7ef4cbbb2011-02-06 11:19:1013237 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413238 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613239 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413240 if (rv == ERR_IO_PENDING)
13241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113242 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613243 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213244 ASSERT_TRUE(response);
13245 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813246 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113247 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13248 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013249
[email protected]7ef4cbbb2011-02-06 11:19:1013250 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013251 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613252 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013253 if (rv == ERR_IO_PENDING)
13254 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113255 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613256 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213257 ASSERT_TRUE(response);
13258 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813259 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013260
asanka463ca4262016-11-16 02:34:3113261 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13262 // auth handler should transition to a DONE state in concert with the remote
13263 // server. But that's not something we can test here with a mock handler.
13264 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13265 auth_handler->state());
13266
[email protected]7ef4cbbb2011-02-06 11:19:1013267 // Read the body since the fourth round was successful. This will also
13268 // release the socket back to the pool.
13269 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613270 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013271 if (rv == ERR_IO_PENDING)
13272 rv = callback.WaitForResult();
13273 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613274 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013275 EXPECT_EQ(0, rv);
13276 // There are still 0 idle sockets, since the trans_compete transaction
13277 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813278 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013279
13280 // The competing request can now finish. Wait for the headers and then
13281 // read the body.
13282 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113283 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613284 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013285 if (rv == ERR_IO_PENDING)
13286 rv = callback.WaitForResult();
13287 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613288 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013289 EXPECT_EQ(0, rv);
13290
13291 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813292 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413293}
13294
[email protected]65041fa2010-05-21 06:56:5313295// This tests the case that a request is issued via http instead of spdy after
13296// npn is negotiated.
bncd16676a2016-07-20 16:23:0113297TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313298 HttpRequestInfo request;
13299 request.method = "GET";
bncce36dca22015-04-21 22:11:2313300 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5313301
13302 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313303 MockWrite(
13304 "GET / HTTP/1.1\r\n"
13305 "Host: www.example.org\r\n"
13306 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313307 };
13308
13309 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213310 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313311 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213312 MockRead("\r\n"),
13313 MockRead("hello world"),
13314 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313315 };
13316
[email protected]8ddf8322012-02-23 18:08:0613317 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613318 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313319
[email protected]bb88e1d32013-05-03 23:11:0713320 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313321
13322 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13323 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713324 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313325
[email protected]49639fa2011-12-20 23:22:4113326 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313327
danakj1fd259a02016-04-16 03:17:0913328 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613329 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313330
tfarina42834112016-09-22 13:38:2013331 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313332
robpercival214763f2016-07-01 23:27:0113333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13334 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313335
bnc691fda62016-08-12 00:43:1613336 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213337 ASSERT_TRUE(response);
13338 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313339 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13340
13341 std::string response_data;
bnc691fda62016-08-12 00:43:1613342 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313343 EXPECT_EQ("hello world", response_data);
13344
13345 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213346 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313347}
[email protected]26ef6582010-06-24 02:30:4713348
bnc55ff9da2015-08-19 18:42:3513349// Simulate the SSL handshake completing with an NPN negotiation followed by an
13350// immediate server closing of the socket.
13351// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113352TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713353 HttpRequestInfo request;
13354 request.method = "GET";
bncce36dca22015-04-21 22:11:2313355 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4713356
[email protected]8ddf8322012-02-23 18:08:0613357 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613358 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713360
bncdf80d44fd2016-07-15 20:27:4113361 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913362 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4113363 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713364
13365 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613366 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713367 };
13368
rch8e6c6c42015-05-01 14:05:1313369 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13370 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713371 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713372
[email protected]49639fa2011-12-20 23:22:4113373 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713374
danakj1fd259a02016-04-16 03:17:0913375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713377
tfarina42834112016-09-22 13:38:2013378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13380 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713381}
[email protected]65d34382010-07-01 18:12:2613382
[email protected]795cbf82013-07-22 09:37:2713383// A subclass of HttpAuthHandlerMock that records the request URL when
13384// it gets it. This is needed since the auth handler may get destroyed
13385// before we get a chance to query it.
13386class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13387 public:
13388 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13389
Chris Watkins7a41d3552017-12-01 02:13:2713390 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713391
13392 protected:
dchengb03027d2014-10-21 12:00:2013393 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13394 const HttpRequestInfo* request,
13395 const CompletionCallback& callback,
13396 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713397 *url_ = request->url;
13398 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13399 credentials, request, callback, auth_token);
13400 }
13401
13402 private:
13403 GURL* url_;
13404};
13405
[email protected]8e6441ca2010-08-19 05:56:3813406// Test that if we cancel the transaction as the connection is completing, that
13407// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113408TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813409 // Setup everything about the connection to complete synchronously, so that
13410 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13411 // for is the callback from the HttpStreamRequest.
13412 // Then cancel the transaction.
13413 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613414 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813415 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613416 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13417 MockRead(SYNCHRONOUS, "hello world"),
13418 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813419 };
13420
[email protected]8e6441ca2010-08-19 05:56:3813421 HttpRequestInfo request;
13422 request.method = "GET";
bncce36dca22015-04-21 22:11:2313423 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813424
[email protected]bb88e1d32013-05-03 23:11:0713425 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813427 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913428 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713429
[email protected]8e6441ca2010-08-19 05:56:3813430 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13431 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713432 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813433
[email protected]49639fa2011-12-20 23:22:4113434 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813435
vishal.b62985ca92015-04-17 08:45:5113436 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113437 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813439 trans.reset(); // Cancel the transaction here.
13440
fdoray92e35a72016-06-10 15:54:5513441 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013442}
13443
[email protected]ecab6e052014-05-16 14:58:1213444// Test that if a transaction is cancelled after receiving the headers, the
13445// stream is drained properly and added back to the socket pool. The main
13446// purpose of this test is to make sure that an HttpStreamParser can be read
13447// from after the HttpNetworkTransaction and the objects it owns have been
13448// deleted.
13449// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113450TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213451 MockRead data_reads[] = {
13452 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13453 MockRead(ASYNC, "Content-Length: 2\r\n"),
13454 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13455 MockRead(ASYNC, "1"),
13456 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13457 // HttpNetworkTransaction has been deleted.
13458 MockRead(ASYNC, "2"),
13459 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13460 };
13461 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13462 session_deps_.socket_factory->AddSocketDataProvider(&data);
13463
danakj1fd259a02016-04-16 03:17:0913464 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213465
13466 {
13467 HttpRequestInfo request;
13468 request.method = "GET";
bncce36dca22015-04-21 22:11:2313469 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213470
dcheng48459ac22014-08-26 00:46:4113471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213472 TestCompletionCallback callback;
13473
tfarina42834112016-09-22 13:38:2013474 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213476 callback.WaitForResult();
13477
13478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213479 ASSERT_TRUE(response);
13480 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213481 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13482
13483 // The transaction and HttpRequestInfo are deleted.
13484 }
13485
13486 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513487 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213488
13489 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113490 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213491}
13492
[email protected]76a505b2010-08-25 06:23:0013493// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113494TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913495 session_deps_.proxy_resolution_service =
13496 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113497 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713498 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013500
[email protected]76a505b2010-08-25 06:23:0013501 HttpRequestInfo request;
13502 request.method = "GET";
bncce36dca22015-04-21 22:11:2313503 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013504
13505 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313506 MockWrite(
13507 "GET http://www.example.org/ HTTP/1.1\r\n"
13508 "Host: www.example.org\r\n"
13509 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013510 };
13511
13512 MockRead data_reads1[] = {
13513 MockRead("HTTP/1.1 200 OK\r\n"),
13514 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13515 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613516 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013517 };
13518
13519 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13520 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713521 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013522
[email protected]49639fa2011-12-20 23:22:4113523 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013524
bnc691fda62016-08-12 00:43:1613525 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913526 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613527 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913528 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13529 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013530
bnc691fda62016-08-12 00:43:1613531 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013533
13534 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113535 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013536
bnc691fda62016-08-12 00:43:1613537 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213538 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013539
13540 EXPECT_TRUE(response->headers->IsKeepAlive());
13541 EXPECT_EQ(200, response->headers->response_code());
13542 EXPECT_EQ(100, response->headers->GetContentLength());
13543 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713544 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13545 HostPortPair::FromString("myproxy:70")),
13546 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913547 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13548 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13549 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013550 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013551
13552 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613553 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013554 TestLoadTimingNotReusedWithPac(load_timing_info,
13555 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013556}
13557
13558// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113559TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913560 session_deps_.proxy_resolution_service =
13561 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113562 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713563 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013565
[email protected]76a505b2010-08-25 06:23:0013566 HttpRequestInfo request;
13567 request.method = "GET";
bncce36dca22015-04-21 22:11:2313568 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013569
13570 // Since we have proxy, should try to establish tunnel.
13571 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713572 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13573 "Host: www.example.org:443\r\n"
13574 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013575
rsleevidb16bb02015-11-12 23:47:1713576 MockWrite("GET / HTTP/1.1\r\n"
13577 "Host: www.example.org\r\n"
13578 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013579 };
13580
13581 MockRead data_reads1[] = {
13582 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13583
13584 MockRead("HTTP/1.1 200 OK\r\n"),
13585 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13586 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613587 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013588 };
13589
13590 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13591 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713592 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613593 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713594 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013595
[email protected]49639fa2011-12-20 23:22:4113596 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013597
bnc691fda62016-08-12 00:43:1613598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913599 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613600 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913601 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13602 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013603
bnc691fda62016-08-12 00:43:1613604 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013606
13607 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113608 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613609 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013610 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013611 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013612 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13613 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013614 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013615 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013616 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13617 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013618
bnc691fda62016-08-12 00:43:1613619 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213620 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013621
13622 EXPECT_TRUE(response->headers->IsKeepAlive());
13623 EXPECT_EQ(200, response->headers->response_code());
13624 EXPECT_EQ(100, response->headers->GetContentLength());
13625 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13626 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713627 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13628 HostPortPair::FromString("myproxy:70")),
13629 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913630 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13631 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13632 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013633
13634 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613635 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013636 TestLoadTimingNotReusedWithPac(load_timing_info,
13637 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013638}
13639
rsleevidb16bb02015-11-12 23:47:1713640// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13641// literal host.
bncd16676a2016-07-20 16:23:0113642TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913643 session_deps_.proxy_resolution_service =
13644 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
rsleevidb16bb02015-11-12 23:47:1713645 BoundTestNetLog log;
13646 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713648
13649 HttpRequestInfo request;
13650 request.method = "GET";
13651 request.url = GURL("https://[::1]:443/");
13652
13653 // Since we have proxy, should try to establish tunnel.
13654 MockWrite data_writes1[] = {
13655 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13656 "Host: [::1]:443\r\n"
13657 "Proxy-Connection: keep-alive\r\n\r\n"),
13658
13659 MockWrite("GET / HTTP/1.1\r\n"
13660 "Host: [::1]\r\n"
13661 "Connection: keep-alive\r\n\r\n"),
13662 };
13663
13664 MockRead data_reads1[] = {
13665 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13666
13667 MockRead("HTTP/1.1 200 OK\r\n"),
13668 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13669 MockRead("Content-Length: 100\r\n\r\n"),
13670 MockRead(SYNCHRONOUS, OK),
13671 };
13672
13673 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13674 data_writes1, arraysize(data_writes1));
13675 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13676 SSLSocketDataProvider ssl(ASYNC, OK);
13677 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13678
13679 TestCompletionCallback callback1;
13680
bnc691fda62016-08-12 00:43:1613681 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713682
bnc691fda62016-08-12 00:43:1613683 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713685
13686 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113687 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713688 TestNetLogEntry::List entries;
13689 log.GetEntries(&entries);
13690 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013691 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13692 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713693 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013694 entries, pos,
13695 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13696 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713697
bnc691fda62016-08-12 00:43:1613698 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213699 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713700
13701 EXPECT_TRUE(response->headers->IsKeepAlive());
13702 EXPECT_EQ(200, response->headers->response_code());
13703 EXPECT_EQ(100, response->headers->GetContentLength());
13704 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13705 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713706 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13707 HostPortPair::FromString("myproxy:70")),
13708 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713709
13710 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613711 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713712 TestLoadTimingNotReusedWithPac(load_timing_info,
13713 CONNECT_TIMING_HAS_SSL_TIMES);
13714}
13715
[email protected]76a505b2010-08-25 06:23:0013716// Test a basic HTTPS GET request through a proxy, but the server hangs up
13717// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113718TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Lily Houghton8c2f97d2018-01-22 05:06:5913719 session_deps_.proxy_resolution_service =
13720 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113721 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713722 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013724
[email protected]76a505b2010-08-25 06:23:0013725 HttpRequestInfo request;
13726 request.method = "GET";
bncce36dca22015-04-21 22:11:2313727 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013728
13729 // Since we have proxy, should try to establish tunnel.
13730 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713731 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13732 "Host: www.example.org:443\r\n"
13733 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013734
rsleevidb16bb02015-11-12 23:47:1713735 MockWrite("GET / HTTP/1.1\r\n"
13736 "Host: www.example.org\r\n"
13737 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013738 };
13739
13740 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0013741 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613742 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013743 };
13744
13745 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13746 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713747 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613748 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713749 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013750
[email protected]49639fa2011-12-20 23:22:4113751 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013752
bnc691fda62016-08-12 00:43:1613753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013754
bnc691fda62016-08-12 00:43:1613755 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013757
13758 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113759 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613760 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013761 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013762 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013763 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13764 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013765 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013766 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013767 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13768 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013769}
13770
[email protected]749eefa82010-09-13 22:14:0313771// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113772TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113773 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913774 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113775 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313776
bnc42331402016-07-25 13:36:1513777 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113778 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313779 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113780 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313781 };
13782
rch8e6c6c42015-05-01 14:05:1313783 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13784 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713785 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313786
[email protected]8ddf8322012-02-23 18:08:0613787 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613788 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713789 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313790
danakj1fd259a02016-04-16 03:17:0913791 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313792
13793 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313794 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013795 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0413796 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713797 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213798 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313799
13800 HttpRequestInfo request;
13801 request.method = "GET";
bncce36dca22015-04-21 22:11:2313802 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313803
13804 // This is the important line that marks this as a preconnect.
13805 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13806
bnc691fda62016-08-12 00:43:1613807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313808
[email protected]41d64e82013-07-03 22:44:2613809 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013810 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13812 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313813}
13814
[email protected]73b8dd222010-11-11 19:55:2413815// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613816// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213817void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713818 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913819 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713820 request_info.url = GURL("https://www.example.com/");
13821 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913822 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713823
[email protected]8ddf8322012-02-23 18:08:0613824 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913825 MockWrite data_writes[] = {
13826 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413827 };
ttuttle859dc7a2015-04-23 19:42:2913828 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713829 session_deps_.socket_factory->AddSocketDataProvider(&data);
13830 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413831
danakj1fd259a02016-04-16 03:17:0913832 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613833 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413834
[email protected]49639fa2011-12-20 23:22:4113835 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013836 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913837 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413838 rv = callback.WaitForResult();
13839 ASSERT_EQ(error, rv);
13840}
13841
bncd16676a2016-07-20 16:23:0113842TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413843 // Just check a grab bag of cert errors.
13844 static const int kErrors[] = {
13845 ERR_CERT_COMMON_NAME_INVALID,
13846 ERR_CERT_AUTHORITY_INVALID,
13847 ERR_CERT_DATE_INVALID,
13848 };
13849 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613850 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13851 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413852 }
13853}
13854
[email protected]bd0b6772011-01-11 19:59:3013855// Ensure that a client certificate is removed from the SSL client auth
13856// cache when:
13857// 1) No proxy is involved.
13858// 2) TLS False Start is disabled.
13859// 3) The initial TLS handshake requests a client certificate.
13860// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113861TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913862 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713863 request_info.url = GURL("https://www.example.com/");
13864 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913865 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713866
[email protected]bd0b6772011-01-11 19:59:3013867 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113868 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013869
13870 // [ssl_]data1 contains the data for the first SSL handshake. When a
13871 // CertificateRequest is received for the first time, the handshake will
13872 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913873 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013874 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913876 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013878
13879 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13880 // False Start is not being used, the result of the SSL handshake will be
13881 // returned as part of the SSLClientSocket::Connect() call. This test
13882 // matches the result of a server sending a handshake_failure alert,
13883 // rather than a Finished message, because it requires a client
13884 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913885 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013886 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713887 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913888 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713889 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013890
13891 // [ssl_]data3 contains the data for the third SSL handshake. When a
13892 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213893 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13894 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013895 // of the HttpNetworkTransaction. Because this test failure is due to
13896 // requiring a client certificate, this fallback handshake should also
13897 // fail.
ttuttle859dc7a2015-04-23 19:42:2913898 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013899 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913901 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713902 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013903
[email protected]80c75f682012-05-26 16:22:1713904 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13905 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213906 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13907 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713908 // of the HttpNetworkTransaction. Because this test failure is due to
13909 // requiring a client certificate, this fallback handshake should also
13910 // fail.
ttuttle859dc7a2015-04-23 19:42:2913911 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713912 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913914 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713915 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713916
danakj1fd259a02016-04-16 03:17:0913917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613918 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013919
[email protected]bd0b6772011-01-11 19:59:3013920 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113921 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013922 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113923 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013924
13925 // Complete the SSL handshake, which should abort due to requiring a
13926 // client certificate.
13927 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113928 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013929
13930 // Indicate that no certificate should be supplied. From the perspective
13931 // of SSLClientCertCache, NULL is just as meaningful as a real
13932 // certificate, so this is the same as supply a
13933 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613934 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113935 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013936
13937 // Ensure the certificate was added to the client auth cache before
13938 // allowing the connection to continue restarting.
13939 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413940 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113941 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413942 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213943 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013944
13945 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713946 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13947 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013948 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113949 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013950
13951 // Ensure that the client certificate is removed from the cache on a
13952 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113953 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413954 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013955}
13956
13957// Ensure that a client certificate is removed from the SSL client auth
13958// cache when:
13959// 1) No proxy is involved.
13960// 2) TLS False Start is enabled.
13961// 3) The initial TLS handshake requests a client certificate.
13962// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113963TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913964 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713965 request_info.url = GURL("https://www.example.com/");
13966 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913967 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713968
[email protected]bd0b6772011-01-11 19:59:3013969 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113970 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013971
13972 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13973 // return successfully after reading up to the peer's Certificate message.
13974 // This is to allow the caller to call SSLClientSocket::Write(), which can
13975 // enqueue application data to be sent in the same packet as the
13976 // ChangeCipherSpec and Finished messages.
13977 // The actual handshake will be finished when SSLClientSocket::Read() is
13978 // called, which expects to process the peer's ChangeCipherSpec and
13979 // Finished messages. If there was an error negotiating with the peer,
13980 // such as due to the peer requiring a client certificate when none was
13981 // supplied, the alert sent by the peer won't be processed until Read() is
13982 // called.
13983
13984 // Like the non-False Start case, when a client certificate is requested by
13985 // the peer, the handshake is aborted during the Connect() call.
13986 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913987 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013988 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713989 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913990 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713991 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013992
13993 // When a client certificate is supplied, Connect() will not be aborted
13994 // when the peer requests the certificate. Instead, the handshake will
13995 // artificially succeed, allowing the caller to write the HTTP request to
13996 // the socket. The handshake messages are not processed until Read() is
13997 // called, which then detects that the handshake was aborted, due to the
13998 // peer sending a handshake_failure because it requires a client
13999 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914000 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014001 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714002 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914003 MockRead data2_reads[] = {
14004 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014005 };
ttuttle859dc7a2015-04-23 19:42:2914006 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714007 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014008
14009 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714010 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14011 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914012 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014013 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714014 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914015 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714016 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014017
[email protected]80c75f682012-05-26 16:22:1714018 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14019 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914020 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714021 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714022 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914023 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714024 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714025
[email protected]7799de12013-05-30 05:52:5114026 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914027 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114028 ssl_data5.cert_request_info = cert_request.get();
14029 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914030 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114031 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14032
danakj1fd259a02016-04-16 03:17:0914033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014035
[email protected]bd0b6772011-01-11 19:59:3014036 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114037 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014038 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114039 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014040
14041 // Complete the SSL handshake, which should abort due to requiring a
14042 // client certificate.
14043 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114044 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014045
14046 // Indicate that no certificate should be supplied. From the perspective
14047 // of SSLClientCertCache, NULL is just as meaningful as a real
14048 // certificate, so this is the same as supply a
14049 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614050 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114051 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014052
14053 // Ensure the certificate was added to the client auth cache before
14054 // allowing the connection to continue restarting.
14055 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414056 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114057 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414058 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214059 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014060
[email protected]bd0b6772011-01-11 19:59:3014061 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714062 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14063 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014064 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114065 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014066
14067 // Ensure that the client certificate is removed from the cache on a
14068 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114069 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414070 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014071}
14072
[email protected]8c405132011-01-11 22:03:1814073// Ensure that a client certificate is removed from the SSL client auth
14074// cache when:
14075// 1) An HTTPS proxy is involved.
14076// 3) The HTTPS proxy requests a client certificate.
14077// 4) The client supplies an invalid/unacceptable certificate for the
14078// proxy.
14079// The test is repeated twice, first for connecting to an HTTPS endpoint,
14080// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114081TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Lily Houghton8c2f97d2018-01-22 05:06:5914082 session_deps_.proxy_resolution_service =
14083 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114084 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714085 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814086
14087 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114088 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814089
14090 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14091 // [ssl_]data[1-3]. Rather than represending the endpoint
14092 // (www.example.com:443), they represent failures with the HTTPS proxy
14093 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914094 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814095 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914097 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714098 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814099
ttuttle859dc7a2015-04-23 19:42:2914100 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814101 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714102 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914103 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714104 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814105
[email protected]80c75f682012-05-26 16:22:1714106 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14107#if 0
ttuttle859dc7a2015-04-23 19:42:2914108 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814109 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714110 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914111 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714112 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714113#endif
[email protected]8c405132011-01-11 22:03:1814114
ttuttle859dc7a2015-04-23 19:42:2914115 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814116 requests[0].url = GURL("https://www.example.com/");
14117 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914118 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814119
14120 requests[1].url = GURL("http://www.example.com/");
14121 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914122 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814123
14124 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714125 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814128
14129 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114130 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014131 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114132 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814133
14134 // Complete the SSL handshake, which should abort due to requiring a
14135 // client certificate.
14136 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114137 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814138
14139 // Indicate that no certificate should be supplied. From the perspective
14140 // of SSLClientCertCache, NULL is just as meaningful as a real
14141 // certificate, so this is the same as supply a
14142 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614143 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114144 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814145
14146 // Ensure the certificate was added to the client auth cache before
14147 // allowing the connection to continue restarting.
14148 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414149 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114150 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414151 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214152 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814153 // Ensure the certificate was NOT cached for the endpoint. This only
14154 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114155 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414156 HostPortPair("www.example.com", 443), &client_cert,
14157 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814158
14159 // Restart the handshake. This will consume ssl_data2, which fails, and
14160 // then consume ssl_data3, which should also fail. The result code is
14161 // checked against what ssl_data3 should return.
14162 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114163 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814164
14165 // Now that the new handshake has failed, ensure that the client
14166 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114167 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414168 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114169 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414170 HostPortPair("www.example.com", 443), &client_cert,
14171 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814172 }
14173}
14174
bncd16676a2016-07-20 16:23:0114175TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614176 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914177 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614179
bnc032658ba2016-09-26 18:17:1514180 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614181
bncdf80d44fd2016-07-15 20:27:4114182 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914183 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814184 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114185 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714186 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614187 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114188 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614189 };
bnc42331402016-07-25 13:36:1514190 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114191 SpdySerializedFrame host1_resp_body(
14192 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514193 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114194 SpdySerializedFrame host2_resp_body(
14195 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614196 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114197 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14198 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314199 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614200 };
14201
eroman36d84e54432016-03-17 03:23:0214202 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214203 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314204 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14205 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714206 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614207
[email protected]aa22b242011-11-16 18:58:2914208 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614209 HttpRequestInfo request1;
14210 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314211 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614212 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014213 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614214
tfarina42834112016-09-22 13:38:2014215 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14217 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614218
14219 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214220 ASSERT_TRUE(response);
14221 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214222 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614223
14224 std::string response_data;
robpercival214763f2016-07-01 23:27:0114225 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614226 EXPECT_EQ("hello!", response_data);
14227
bnca4d611d2016-09-22 19:55:3714228 // Preload mail.example.com into HostCache.
14229 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014230 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614231 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014232 std::unique_ptr<HostResolver::Request> request;
14233 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14234 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014235 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714237 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114238 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614239
14240 HttpRequestInfo request2;
14241 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714242 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614243 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014244 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614245
tfarina42834112016-09-22 13:38:2014246 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14248 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614249
14250 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214251 ASSERT_TRUE(response);
14252 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214253 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614254 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214255 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114256 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614257 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614258}
14259
bncd16676a2016-07-20 16:23:0114260TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214261 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914262 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214264
bnc032658ba2016-09-26 18:17:1514265 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214266
bncdf80d44fd2016-07-15 20:27:4114267 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914268 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814269 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114270 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714271 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214272 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114273 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214274 };
bnc42331402016-07-25 13:36:1514275 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114276 SpdySerializedFrame host1_resp_body(
14277 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514278 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114279 SpdySerializedFrame host2_resp_body(
14280 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214281 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114282 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14283 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314284 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214285 };
14286
eroman36d84e54432016-03-17 03:23:0214287 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214288 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314289 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14290 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714291 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214292
14293 TestCompletionCallback callback;
14294 HttpRequestInfo request1;
14295 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314296 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214297 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014298 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214299
tfarina42834112016-09-22 13:38:2014300 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14302 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214303
14304 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214305 ASSERT_TRUE(response);
14306 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214307 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214308
14309 std::string response_data;
robpercival214763f2016-07-01 23:27:0114310 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214311 EXPECT_EQ("hello!", response_data);
14312
14313 HttpRequestInfo request2;
14314 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714315 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214316 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014317 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214318
tfarina42834112016-09-22 13:38:2014319 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114320 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14321 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214322
14323 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214324 ASSERT_TRUE(response);
14325 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214326 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214327 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214328 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114329 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214330 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214331}
14332
bnc8016c1f2017-03-31 02:11:2914333// Regression test for https://crbug.com/546991.
14334// The server might not be able to serve an IP pooled request, and might send a
14335// 421 Misdirected Request response status to indicate this.
14336// HttpNetworkTransaction should reset the request and retry without IP pooling.
14337TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14338 // Two hosts resolve to the same IP address.
14339 const std::string ip_addr = "1.2.3.4";
14340 IPAddress ip;
14341 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14342 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14343
Jeremy Roman0579ed62017-08-29 15:56:1914344 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914345 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14346 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14347
14348 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14349
14350 // Two requests on the first connection.
14351 SpdySerializedFrame req1(
14352 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14353 spdy_util_.UpdateWithStreamDestruction(1);
14354 SpdySerializedFrame req2(
14355 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14356 SpdySerializedFrame rst(
14357 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14358 MockWrite writes1[] = {
14359 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14360 CreateMockWrite(rst, 6),
14361 };
14362
14363 // The first one succeeds, the second gets error 421 Misdirected Request.
14364 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14365 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14366 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714367 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914368 SpdySerializedFrame resp2(
14369 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14370 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14371 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14372
14373 MockConnect connect1(ASYNC, OK, peer_addr);
14374 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14375 arraysize(writes1));
14376 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14377
14378 AddSSLSocketData();
14379
14380 // Retry the second request on a second connection.
14381 SpdyTestUtil spdy_util2;
14382 SpdySerializedFrame req3(
14383 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14384 MockWrite writes2[] = {
14385 CreateMockWrite(req3, 0),
14386 };
14387
14388 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14389 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14390 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14391 MockRead(ASYNC, 0, 3)};
14392
14393 MockConnect connect2(ASYNC, OK, peer_addr);
14394 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14395 arraysize(writes2));
14396 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14397
14398 AddSSLSocketData();
14399
14400 // Preload mail.example.org into HostCache.
14401 HostPortPair host_port("mail.example.org", 443);
14402 HostResolver::RequestInfo resolve_info(host_port);
14403 AddressList ignored;
14404 std::unique_ptr<HostResolver::Request> request;
14405 TestCompletionCallback callback;
14406 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14407 &ignored, callback.callback(),
14408 &request, NetLogWithSource());
14409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14410 rv = callback.WaitForResult();
14411 EXPECT_THAT(rv, IsOk());
14412
14413 HttpRequestInfo request1;
14414 request1.method = "GET";
14415 request1.url = GURL("https://www.example.org/");
14416 request1.load_flags = 0;
14417 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14418
14419 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14421 rv = callback.WaitForResult();
14422 EXPECT_THAT(rv, IsOk());
14423
14424 const HttpResponseInfo* response = trans1.GetResponseInfo();
14425 ASSERT_TRUE(response);
14426 ASSERT_TRUE(response->headers);
14427 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14428 EXPECT_TRUE(response->was_fetched_via_spdy);
14429 EXPECT_TRUE(response->was_alpn_negotiated);
14430 std::string response_data;
14431 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14432 EXPECT_EQ("hello!", response_data);
14433
14434 HttpRequestInfo request2;
14435 request2.method = "GET";
14436 request2.url = GURL("https://mail.example.org/");
14437 request2.load_flags = 0;
14438 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14439
14440 BoundTestNetLog log;
14441 rv = trans2.Start(&request2, callback.callback(), log.bound());
14442 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14443 rv = callback.WaitForResult();
14444 EXPECT_THAT(rv, IsOk());
14445
14446 response = trans2.GetResponseInfo();
14447 ASSERT_TRUE(response);
14448 ASSERT_TRUE(response->headers);
14449 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14450 EXPECT_TRUE(response->was_fetched_via_spdy);
14451 EXPECT_TRUE(response->was_alpn_negotiated);
14452 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14453 EXPECT_EQ("hello!", response_data);
14454
14455 TestNetLogEntry::List entries;
14456 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914457 ExpectLogContainsSomewhere(
14458 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914459 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914460}
14461
14462// Test that HTTP 421 responses are properly returned to the caller if received
14463// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14464// portions of the response.
14465TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14466 // Two hosts resolve to the same IP address.
14467 const std::string ip_addr = "1.2.3.4";
14468 IPAddress ip;
14469 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14470 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14471
Jeremy Roman0579ed62017-08-29 15:56:1914472 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914473 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14474 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14475
14476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14477
14478 // Two requests on the first connection.
14479 SpdySerializedFrame req1(
14480 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14481 spdy_util_.UpdateWithStreamDestruction(1);
14482 SpdySerializedFrame req2(
14483 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14484 SpdySerializedFrame rst(
14485 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14486 MockWrite writes1[] = {
14487 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14488 CreateMockWrite(rst, 6),
14489 };
14490
14491 // The first one succeeds, the second gets error 421 Misdirected Request.
14492 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14493 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14494 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714495 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914496 SpdySerializedFrame resp2(
14497 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14498 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14499 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14500
14501 MockConnect connect1(ASYNC, OK, peer_addr);
14502 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14503 arraysize(writes1));
14504 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14505
14506 AddSSLSocketData();
14507
14508 // Retry the second request on a second connection. It returns 421 Misdirected
14509 // Retry again.
14510 SpdyTestUtil spdy_util2;
14511 SpdySerializedFrame req3(
14512 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14513 MockWrite writes2[] = {
14514 CreateMockWrite(req3, 0),
14515 };
14516
14517 SpdySerializedFrame resp3(
14518 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14519 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14520 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14521 MockRead(ASYNC, 0, 3)};
14522
14523 MockConnect connect2(ASYNC, OK, peer_addr);
14524 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14525 arraysize(writes2));
14526 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14527
14528 AddSSLSocketData();
14529
14530 // Preload mail.example.org into HostCache.
14531 HostPortPair host_port("mail.example.org", 443);
14532 HostResolver::RequestInfo resolve_info(host_port);
14533 AddressList ignored;
14534 std::unique_ptr<HostResolver::Request> request;
14535 TestCompletionCallback callback;
14536 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14537 &ignored, callback.callback(),
14538 &request, NetLogWithSource());
14539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14540 rv = callback.WaitForResult();
14541 EXPECT_THAT(rv, IsOk());
14542
14543 HttpRequestInfo request1;
14544 request1.method = "GET";
14545 request1.url = GURL("https://www.example.org/");
14546 request1.load_flags = 0;
14547 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14548
14549 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14551 rv = callback.WaitForResult();
14552 EXPECT_THAT(rv, IsOk());
14553
14554 const HttpResponseInfo* response = trans1.GetResponseInfo();
14555 ASSERT_TRUE(response);
14556 ASSERT_TRUE(response->headers);
14557 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14558 EXPECT_TRUE(response->was_fetched_via_spdy);
14559 EXPECT_TRUE(response->was_alpn_negotiated);
14560 std::string response_data;
14561 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14562 EXPECT_EQ("hello!", response_data);
14563
14564 HttpRequestInfo request2;
14565 request2.method = "GET";
14566 request2.url = GURL("https://mail.example.org/");
14567 request2.load_flags = 0;
14568 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14569
14570 BoundTestNetLog log;
14571 rv = trans2.Start(&request2, callback.callback(), log.bound());
14572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14573 rv = callback.WaitForResult();
14574 EXPECT_THAT(rv, IsOk());
14575
14576 // After a retry, the 421 Misdirected Request is reported back up to the
14577 // caller.
14578 response = trans2.GetResponseInfo();
14579 ASSERT_TRUE(response);
14580 ASSERT_TRUE(response->headers);
14581 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14582 EXPECT_TRUE(response->was_fetched_via_spdy);
14583 EXPECT_TRUE(response->was_alpn_negotiated);
14584 EXPECT_TRUE(response->ssl_info.cert);
14585 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14586 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914587}
14588
bnc6dcd8192017-05-25 20:11:5014589class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614590 public:
14591 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014592 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714593 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614594
dchengb03027d2014-10-21 12:00:2014595 int ResolveFromCache(const RequestInfo& info,
14596 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014597 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014598 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014599 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014600 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614601 return rv;
14602 }
14603
[email protected]e3ceb682011-06-28 23:55:4614604 private:
[email protected]e3ceb682011-06-28 23:55:4614605 const HostPortPair host_port_;
14606};
14607
bncd16676a2016-07-20 16:23:0114608TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314609 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614610 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914611 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714612 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614614
bnc032658ba2016-09-26 18:17:1514615 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614616
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]e3ceb682011-06-28 23:55:4614622 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114623 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614624 };
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]e3ceb682011-06-28 23:55:4614631 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]e3ceb682011-06-28 23:55:4614635 };
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]e3ceb682011-06-28 23:55:4614642
[email protected]aa22b242011-11-16 18:58:2914643 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614644 HttpRequestInfo request1;
14645 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314646 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614647 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014648 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614649
tfarina42834112016-09-22 13:38:2014650 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14652 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614653
14654 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214655 ASSERT_TRUE(response);
14656 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214657 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614658
14659 std::string response_data;
robpercival214763f2016-07-01 23:27:0114660 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614661 EXPECT_EQ("hello!", response_data);
14662
14663 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714664 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614665 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014666 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014667 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14668 &ignored, callback.callback(),
14669 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714671 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114672 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614673
14674 HttpRequestInfo request2;
14675 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714676 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614677 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014678 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614679
tfarina42834112016-09-22 13:38:2014680 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14682 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614683
14684 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214685 ASSERT_TRUE(response);
14686 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214687 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614688 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214689 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114690 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614691 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614692}
14693
bncd16676a2016-07-20 16:23:0114694TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314695 const std::string https_url = "https://www.example.org:8080/";
14696 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414697
14698 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114699 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914700 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414701
14702 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114703 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414704 };
14705
bnc42331402016-07-25 13:36:1514706 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114707 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14708 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914709 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414710
rch8e6c6c42015-05-01 14:05:1314711 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14712 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414713 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714714 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414715
14716 // HTTP GET for the HTTP URL
14717 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314718 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414719 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314720 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414721 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414722 };
14723
14724 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314725 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14726 MockRead(ASYNC, 2, "hello"),
14727 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414728 };
14729
rch8e6c6c42015-05-01 14:05:1314730 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14731 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414732
[email protected]8450d722012-07-02 19:14:0414733 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614734 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714735 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14737 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414738
danakj1fd259a02016-04-16 03:17:0914739 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414740
14741 // Start the first transaction to set up the SpdySession
14742 HttpRequestInfo request1;
14743 request1.method = "GET";
14744 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414745 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014746 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414747 TestCompletionCallback callback1;
14748 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014749 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514750 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414751
robpercival214763f2016-07-01 23:27:0114752 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414753 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14754
14755 // Now, start the HTTP request
14756 HttpRequestInfo request2;
14757 request2.method = "GET";
14758 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414759 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014760 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414761 TestCompletionCallback callback2;
14762 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014763 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514764 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414765
robpercival214763f2016-07-01 23:27:0114766 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414767 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14768}
14769
bnc5452e2a2015-05-08 16:27:4214770// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14771// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114772TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514773 url::SchemeHostPort server("https", "www.example.org", 443);
14774 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214775
bnc8bef8da22016-05-30 01:28:2514776 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214777 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614778 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14780
14781 // No data should be read from the alternative, because HTTP/1.1 is
14782 // negotiated.
14783 StaticSocketDataProvider data;
14784 session_deps_.socket_factory->AddSocketDataProvider(&data);
14785
14786 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614787 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214788 // mocked. This way the request relies on the alternate Job.
14789 StaticSocketDataProvider data_refused;
14790 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14791 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14792
zhongyi3d4a55e72016-04-22 20:36:4614793 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914794 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014795 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214796 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114797 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214798 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114799 http_server_properties->SetHttp2AlternativeService(
14800 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214801
bnc5452e2a2015-05-08 16:27:4214802 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614803 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214804 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514805 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214806 TestCompletionCallback callback;
14807
14808 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214809 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014810 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214811 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214812}
14813
bnc40448a532015-05-11 19:13:1414814// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614815// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414816// succeeds, the request should succeed, even if the latter fails because
14817// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114818TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514819 url::SchemeHostPort server("https", "www.example.org", 443);
14820 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414821
14822 // Negotiate HTTP/1.1 with alternative.
14823 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614824 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414825 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14826
14827 // No data should be read from the alternative, because HTTP/1.1 is
14828 // negotiated.
14829 StaticSocketDataProvider data;
14830 session_deps_.socket_factory->AddSocketDataProvider(&data);
14831
zhongyi3d4a55e72016-04-22 20:36:4614832 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414833 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614834 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414835 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14836
14837 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514838 MockWrite("GET / HTTP/1.1\r\n"
14839 "Host: www.example.org\r\n"
14840 "Connection: keep-alive\r\n\r\n"),
14841 MockWrite("GET /second HTTP/1.1\r\n"
14842 "Host: www.example.org\r\n"
14843 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414844 };
14845
14846 MockRead http_reads[] = {
14847 MockRead("HTTP/1.1 200 OK\r\n"),
14848 MockRead("Content-Type: text/html\r\n"),
14849 MockRead("Content-Length: 6\r\n\r\n"),
14850 MockRead("foobar"),
14851 MockRead("HTTP/1.1 200 OK\r\n"),
14852 MockRead("Content-Type: text/html\r\n"),
14853 MockRead("Content-Length: 7\r\n\r\n"),
14854 MockRead("another"),
14855 };
14856 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14857 http_writes, arraysize(http_writes));
14858 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14859
zhongyi3d4a55e72016-04-22 20:36:4614860 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014862 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414863 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114864 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214865 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114866 http_server_properties->SetHttp2AlternativeService(
14867 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414868
14869 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14870 HttpRequestInfo request1;
14871 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514872 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414873 request1.load_flags = 0;
14874 TestCompletionCallback callback1;
14875
tfarina42834112016-09-22 13:38:2014876 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414877 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114878 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414879
14880 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214881 ASSERT_TRUE(response1);
14882 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414883 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14884
14885 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114886 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414887 EXPECT_EQ("foobar", response_data1);
14888
14889 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14890 // for alternative service.
14891 EXPECT_TRUE(
14892 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14893
zhongyi3d4a55e72016-04-22 20:36:4614894 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414895 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614896 // to server.
bnc40448a532015-05-11 19:13:1414897 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14898 HttpRequestInfo request2;
14899 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514900 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414901 request2.load_flags = 0;
14902 TestCompletionCallback callback2;
14903
tfarina42834112016-09-22 13:38:2014904 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414905 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114906 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414907
14908 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214909 ASSERT_TRUE(response2);
14910 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414911 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14912
14913 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114914 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414915 EXPECT_EQ("another", response_data2);
14916}
14917
bnc5452e2a2015-05-08 16:27:4214918// Alternative service requires HTTP/2 (or SPDY), but there is already a
14919// HTTP/1.1 socket open to the alternative server. That socket should not be
14920// used.
bncd16676a2016-07-20 16:23:0114921TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614922 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214923 HostPortPair alternative("alternative.example.org", 443);
14924 std::string origin_url = "https://origin.example.org:443";
14925 std::string alternative_url = "https://alternative.example.org:443";
14926
14927 // Negotiate HTTP/1.1 with alternative.example.org.
14928 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614929 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14931
14932 // HTTP/1.1 data for |request1| and |request2|.
14933 MockWrite http_writes[] = {
14934 MockWrite(
14935 "GET / HTTP/1.1\r\n"
14936 "Host: alternative.example.org\r\n"
14937 "Connection: keep-alive\r\n\r\n"),
14938 MockWrite(
14939 "GET / HTTP/1.1\r\n"
14940 "Host: alternative.example.org\r\n"
14941 "Connection: keep-alive\r\n\r\n"),
14942 };
14943
14944 MockRead http_reads[] = {
14945 MockRead(
14946 "HTTP/1.1 200 OK\r\n"
14947 "Content-Type: text/html; charset=iso-8859-1\r\n"
14948 "Content-Length: 40\r\n\r\n"
14949 "first HTTP/1.1 response from alternative"),
14950 MockRead(
14951 "HTTP/1.1 200 OK\r\n"
14952 "Content-Type: text/html; charset=iso-8859-1\r\n"
14953 "Content-Length: 41\r\n\r\n"
14954 "second HTTP/1.1 response from alternative"),
14955 };
14956 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14957 http_writes, arraysize(http_writes));
14958 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14959
14960 // This test documents that an alternate Job should not pool to an already
14961 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614962 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214963 StaticSocketDataProvider data_refused;
14964 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14965 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14966
zhongyi3d4a55e72016-04-22 20:36:4614967 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014969 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214970 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114971 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214972 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114973 http_server_properties->SetHttp2AlternativeService(
14974 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214975
14976 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214977 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614978 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214979 request1.method = "GET";
14980 request1.url = GURL(alternative_url);
14981 request1.load_flags = 0;
14982 TestCompletionCallback callback1;
14983
tfarina42834112016-09-22 13:38:2014984 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114985 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614986 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214987 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214988 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214989 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214990 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214991 EXPECT_FALSE(response1->was_fetched_via_spdy);
14992 std::string response_data1;
bnc691fda62016-08-12 00:43:1614993 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214994 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14995
14996 // Request for origin.example.org, which has an alternative service. This
14997 // will start two Jobs: the alternative looks for connections to pool to,
14998 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614999 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215000 // this request fails.
bnc5452e2a2015-05-08 16:27:4215001 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615002 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215003 request2.method = "GET";
15004 request2.url = GURL(origin_url);
15005 request2.load_flags = 0;
15006 TestCompletionCallback callback2;
15007
tfarina42834112016-09-22 13:38:2015008 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115009 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215010
15011 // Another transaction to alternative. This is to test that the HTTP/1.1
15012 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215013 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615014 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215015 request3.method = "GET";
15016 request3.url = GURL(alternative_url);
15017 request3.load_flags = 0;
15018 TestCompletionCallback callback3;
15019
tfarina42834112016-09-22 13:38:2015020 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115021 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615022 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215023 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215024 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215025 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215026 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215027 EXPECT_FALSE(response3->was_fetched_via_spdy);
15028 std::string response_data3;
bnc691fda62016-08-12 00:43:1615029 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215030 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15031}
15032
bncd16676a2016-07-20 16:23:0115033TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315034 const std::string https_url = "https://www.example.org:8080/";
15035 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415036
rdsmithebb50aa2015-11-12 03:44:3815037 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115038 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815039
[email protected]8450d722012-07-02 19:14:0415040 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315041 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115042 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415043 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115044 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915045 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115046 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215047 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915048
15049 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915050 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715051 req2_block[kHttp2MethodHeader] = "GET";
15052 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15053 req2_block[kHttp2SchemeHeader] = "http";
15054 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115055 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515056 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415057
15058 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115059 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15060 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415061 };
15062
bncdf80d44fd2016-07-15 20:27:4115063 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515064 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115065 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515066 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115067 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15068 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815069 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115070 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815071 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515072 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115073 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315074 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115075 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315076 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115077 CreateMockRead(wrapped_resp1, 4),
15078 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315079 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115080 CreateMockRead(resp2, 8),
15081 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315082 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15083 };
[email protected]8450d722012-07-02 19:14:0415084
mmenke666a6fea2015-12-19 04:16:3315085 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15086 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415087 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715088 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415089
Lily Houghton8c2f97d2018-01-22 05:06:5915090 session_deps_.proxy_resolution_service =
15091 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115092 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715093 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415094 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615095 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415097 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615098 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15100 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415101
danakj1fd259a02016-04-16 03:17:0915102 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415103
15104 // Start the first transaction to set up the SpdySession
15105 HttpRequestInfo request1;
15106 request1.method = "GET";
15107 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415108 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015109 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415110 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015111 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415112
mmenke666a6fea2015-12-19 04:16:3315113 // This pause is a hack to avoid running into https://crbug.com/497228.
15114 data1.RunUntilPaused();
15115 base::RunLoop().RunUntilIdle();
15116 data1.Resume();
robpercival214763f2016-07-01 23:27:0115117 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415118 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15119
[email protected]f6c63db52013-02-02 00:35:2215120 LoadTimingInfo load_timing_info1;
15121 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15122 TestLoadTimingNotReusedWithPac(load_timing_info1,
15123 CONNECT_TIMING_HAS_SSL_TIMES);
15124
mmenke666a6fea2015-12-19 04:16:3315125 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415126 HttpRequestInfo request2;
15127 request2.method = "GET";
15128 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415129 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015130 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415131 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015132 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415133
mmenke666a6fea2015-12-19 04:16:3315134 // This pause is a hack to avoid running into https://crbug.com/497228.
15135 data1.RunUntilPaused();
15136 base::RunLoop().RunUntilIdle();
15137 data1.Resume();
robpercival214763f2016-07-01 23:27:0115138 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315139
[email protected]8450d722012-07-02 19:14:0415140 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215141
15142 LoadTimingInfo load_timing_info2;
15143 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15144 // The established SPDY sessions is considered reused by the HTTP request.
15145 TestLoadTimingReusedWithPac(load_timing_info2);
15146 // HTTP requests over a SPDY session should have a different connection
15147 // socket_log_id than requests over a tunnel.
15148 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415149}
15150
[email protected]2d88e7d2012-07-19 17:55:1715151// Test that in the case where we have a SPDY session to a SPDY proxy
15152// that we do not pool other origins that resolve to the same IP when
15153// the certificate does not match the new origin.
15154// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115155TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315156 const std::string url1 = "http://www.example.org/";
15157 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715158 const std::string ip_addr = "1.2.3.4";
15159
rdsmithebb50aa2015-11-12 03:44:3815160 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115161 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815162
[email protected]2d88e7d2012-07-19 17:55:1715163 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615164 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315165 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115166 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515167 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715168
15169 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115170 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715171 };
15172
bnc42331402016-07-25 13:36:1515173 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115174 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715175 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115176 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15177 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715178 };
15179
mmenke666a6fea2015-12-19 04:16:3315180 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15181 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215182 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915183 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715184 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15185 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315186 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715187
15188 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115189 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915190 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715191
15192 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115193 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715194 };
15195
bnc42331402016-07-25 13:36:1515196 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115197 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15198 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315199 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715200
mmenke666a6fea2015-12-19 04:16:3315201 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15202 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715203 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315204 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715205
15206 // Set up a proxy config that sends HTTP requests to a proxy, and
15207 // all others direct.
15208 ProxyConfig proxy_config;
15209 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Lily Houghton8c2f97d2018-01-22 05:06:5915210 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1915211 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815212 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715213
bncce36dca22015-04-21 22:11:2315214 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615215 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715216 // Load a valid cert. Note, that this does not need to
15217 // be valid for proxy because the MockSSLClientSocket does
15218 // not actually verify it. But SpdySession will use this
15219 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915220 ssl1.ssl_info.cert =
15221 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15222 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15224 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715225
15226 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615227 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315228 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15229 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715230
Jeremy Roman0579ed62017-08-29 15:56:1915231 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315232 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715233 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715234
danakj1fd259a02016-04-16 03:17:0915235 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715236
15237 // Start the first transaction to set up the SpdySession
15238 HttpRequestInfo request1;
15239 request1.method = "GET";
15240 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715241 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015242 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715243 TestCompletionCallback callback1;
15244 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015245 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315246 // This pause is a hack to avoid running into https://crbug.com/497228.
15247 data1.RunUntilPaused();
15248 base::RunLoop().RunUntilIdle();
15249 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715250
robpercival214763f2016-07-01 23:27:0115251 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715252 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15253
15254 // Now, start the HTTP request
15255 HttpRequestInfo request2;
15256 request2.method = "GET";
15257 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715258 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015259 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715260 TestCompletionCallback callback2;
15261 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015262 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515263 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715264
15265 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115266 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715267 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15268}
15269
[email protected]85f97342013-04-17 06:12:2415270// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15271// error) in SPDY session, removes the socket from pool and closes the SPDY
15272// session. Verify that new url's from the same HttpNetworkSession (and a new
15273// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115274TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315275 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415276
15277 MockRead reads1[] = {
15278 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15279 };
15280
mmenke11eb5152015-06-09 14:50:5015281 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415282
bncdf80d44fd2016-07-15 20:27:4115283 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915284 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415285 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115286 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415287 };
15288
bnc42331402016-07-25 13:36:1515289 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115290 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415291 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115292 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15293 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415294 };
15295
mmenke11eb5152015-06-09 14:50:5015296 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15297 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415298
[email protected]85f97342013-04-17 06:12:2415299 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615300 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015301 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15302 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415303
15304 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615305 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15307 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415308
danakj1fd259a02016-04-16 03:17:0915309 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015310 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415311
15312 // Start the first transaction to set up the SpdySession and verify that
15313 // connection was closed.
15314 HttpRequestInfo request1;
15315 request1.method = "GET";
15316 request1.url = GURL(https_url);
15317 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015318 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415319 TestCompletionCallback callback1;
15320 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015321 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115322 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415323
15324 // Now, start the second request and make sure it succeeds.
15325 HttpRequestInfo request2;
15326 request2.method = "GET";
15327 request2.url = GURL(https_url);
15328 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015329 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415330 TestCompletionCallback callback2;
15331 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015332 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415333
robpercival214763f2016-07-01 23:27:0115334 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415335 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15336}
15337
bncd16676a2016-07-20 16:23:0115338TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315339 ClientSocketPoolManager::set_max_sockets_per_group(
15340 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15341 ClientSocketPoolManager::set_max_sockets_per_pool(
15342 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15343
15344 // Use two different hosts with different IPs so they don't get pooled.
15345 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15346 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315348
15349 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615350 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315351 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615352 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15355
bncdf80d44fd2016-07-15 20:27:4115356 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915357 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315358 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115359 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315360 };
bnc42331402016-07-25 13:36:1515361 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115362 SpdySerializedFrame host1_resp_body(
15363 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315364 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115365 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915366 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315367 };
15368
rdsmithebb50aa2015-11-12 03:44:3815369 // Use a separate test instance for the separate SpdySession that will be
15370 // created.
bncd16676a2016-07-20 16:23:0115371 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915372 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815373 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15374 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315375 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15376
bncdf80d44fd2016-07-15 20:27:4115377 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915378 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315379 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115380 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315381 };
bnc42331402016-07-25 13:36:1515382 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115383 SpdySerializedFrame host2_resp_body(
15384 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315385 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115386 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915387 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315388 };
15389
Jeremy Roman0579ed62017-08-29 15:56:1915390 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815391 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15392 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315393 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15394
15395 MockWrite http_write[] = {
15396 MockWrite("GET / HTTP/1.1\r\n"
15397 "Host: www.a.com\r\n"
15398 "Connection: keep-alive\r\n\r\n"),
15399 };
15400
15401 MockRead http_read[] = {
15402 MockRead("HTTP/1.1 200 OK\r\n"),
15403 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15404 MockRead("Content-Length: 6\r\n\r\n"),
15405 MockRead("hello!"),
15406 };
15407 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15408 http_write, arraysize(http_write));
15409 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15410
15411 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415412 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15413 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315414 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615415 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315416
15417 TestCompletionCallback callback;
15418 HttpRequestInfo request1;
15419 request1.method = "GET";
15420 request1.url = GURL("https://www.a.com/");
15421 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815422 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915423 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315424
tfarina42834112016-09-22 13:38:2015425 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115426 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15427 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315428
15429 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215430 ASSERT_TRUE(response);
15431 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215432 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315433 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215434 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315435
15436 std::string response_data;
robpercival214763f2016-07-01 23:27:0115437 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315438 EXPECT_EQ("hello!", response_data);
15439 trans.reset();
15440 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615441 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315442
15443 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415444 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15445 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315446 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615447 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315448 HttpRequestInfo request2;
15449 request2.method = "GET";
15450 request2.url = GURL("https://www.b.com/");
15451 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815452 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915453 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315454
tfarina42834112016-09-22 13:38:2015455 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15457 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315458
15459 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215460 ASSERT_TRUE(response);
15461 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215462 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315463 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215464 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115465 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315466 EXPECT_EQ("hello!", response_data);
15467 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615468 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315469 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615470 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315471
15472 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415473 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15474 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315475 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615476 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315477 HttpRequestInfo request3;
15478 request3.method = "GET";
15479 request3.url = GURL("http://www.a.com/");
15480 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815481 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915482 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315483
tfarina42834112016-09-22 13:38:2015484 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15486 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315487
15488 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215489 ASSERT_TRUE(response);
15490 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315491 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15492 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215493 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115494 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315495 EXPECT_EQ("hello!", response_data);
15496 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615497 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315498 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615499 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315500}
15501
bncd16676a2016-07-20 16:23:0115502TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415503 HttpRequestInfo request;
15504 request.method = "GET";
bncce36dca22015-04-21 22:11:2315505 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415506
danakj1fd259a02016-04-16 03:17:0915507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415509
ttuttled9dbc652015-09-29 20:00:5915510 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415511 StaticSocketDataProvider data;
15512 data.set_connect_data(mock_connect);
15513 session_deps_.socket_factory->AddSocketDataProvider(&data);
15514
15515 TestCompletionCallback callback;
15516
tfarina42834112016-09-22 13:38:2015517 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415519
15520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115521 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415522
[email protected]79e1fd62013-06-20 06:50:0415523 // We don't care whether this succeeds or fails, but it shouldn't crash.
15524 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615525 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715526
15527 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615528 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715529 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115530 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915531
15532 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615533 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915534 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415535}
15536
bncd16676a2016-07-20 16:23:0115537TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415538 HttpRequestInfo request;
15539 request.method = "GET";
bncce36dca22015-04-21 22:11:2315540 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415541
danakj1fd259a02016-04-16 03:17:0915542 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615543 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415544
ttuttled9dbc652015-09-29 20:00:5915545 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415546 StaticSocketDataProvider data;
15547 data.set_connect_data(mock_connect);
15548 session_deps_.socket_factory->AddSocketDataProvider(&data);
15549
15550 TestCompletionCallback callback;
15551
tfarina42834112016-09-22 13:38:2015552 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415554
15555 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115556 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415557
[email protected]79e1fd62013-06-20 06:50:0415558 // We don't care whether this succeeds or fails, but it shouldn't crash.
15559 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615560 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715561
15562 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615563 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715564 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115565 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915566
15567 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615568 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915569 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415570}
15571
bncd16676a2016-07-20 16:23:0115572TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415573 HttpRequestInfo request;
15574 request.method = "GET";
bncce36dca22015-04-21 22:11:2315575 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415576
danakj1fd259a02016-04-16 03:17:0915577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615578 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415579
15580 MockWrite data_writes[] = {
15581 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15582 };
15583 MockRead data_reads[] = {
15584 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15585 };
15586
15587 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15588 data_writes, arraysize(data_writes));
15589 session_deps_.socket_factory->AddSocketDataProvider(&data);
15590
15591 TestCompletionCallback callback;
15592
tfarina42834112016-09-22 13:38:2015593 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415595
15596 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115597 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415598
[email protected]79e1fd62013-06-20 06:50:0415599 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615600 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415601 EXPECT_TRUE(request_headers.HasHeader("Host"));
15602}
15603
bncd16676a2016-07-20 16:23:0115604TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415605 HttpRequestInfo request;
15606 request.method = "GET";
bncce36dca22015-04-21 22:11:2315607 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415608
danakj1fd259a02016-04-16 03:17:0915609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415611
15612 MockWrite data_writes[] = {
15613 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15614 };
15615 MockRead data_reads[] = {
15616 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15617 };
15618
15619 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15620 data_writes, arraysize(data_writes));
15621 session_deps_.socket_factory->AddSocketDataProvider(&data);
15622
15623 TestCompletionCallback callback;
15624
tfarina42834112016-09-22 13:38:2015625 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415627
15628 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115629 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415630
[email protected]79e1fd62013-06-20 06:50:0415631 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615632 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415633 EXPECT_TRUE(request_headers.HasHeader("Host"));
15634}
15635
bncd16676a2016-07-20 16:23:0115636TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415637 HttpRequestInfo request;
15638 request.method = "GET";
bncce36dca22015-04-21 22:11:2315639 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415640
danakj1fd259a02016-04-16 03:17:0915641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415643
15644 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315645 MockWrite(
15646 "GET / HTTP/1.1\r\n"
15647 "Host: www.example.org\r\n"
15648 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415649 };
15650 MockRead data_reads[] = {
15651 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15652 };
15653
15654 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15655 data_writes, arraysize(data_writes));
15656 session_deps_.socket_factory->AddSocketDataProvider(&data);
15657
15658 TestCompletionCallback callback;
15659
tfarina42834112016-09-22 13:38:2015660 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415662
15663 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115664 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415665
[email protected]79e1fd62013-06-20 06:50:0415666 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615667 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415668 EXPECT_TRUE(request_headers.HasHeader("Host"));
15669}
15670
bncd16676a2016-07-20 16:23:0115671TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415672 HttpRequestInfo request;
15673 request.method = "GET";
bncce36dca22015-04-21 22:11:2315674 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415675
danakj1fd259a02016-04-16 03:17:0915676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415678
15679 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315680 MockWrite(
15681 "GET / HTTP/1.1\r\n"
15682 "Host: www.example.org\r\n"
15683 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415684 };
15685 MockRead data_reads[] = {
15686 MockRead(ASYNC, ERR_CONNECTION_RESET),
15687 };
15688
15689 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15690 data_writes, arraysize(data_writes));
15691 session_deps_.socket_factory->AddSocketDataProvider(&data);
15692
15693 TestCompletionCallback callback;
15694
tfarina42834112016-09-22 13:38:2015695 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415697
15698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115699 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415700
[email protected]79e1fd62013-06-20 06:50:0415701 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615702 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415703 EXPECT_TRUE(request_headers.HasHeader("Host"));
15704}
15705
bncd16676a2016-07-20 16:23:0115706TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415707 HttpRequestInfo request;
15708 request.method = "GET";
bncce36dca22015-04-21 22:11:2315709 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415710 request.extra_headers.SetHeader("X-Foo", "bar");
15711
danakj1fd259a02016-04-16 03:17:0915712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415714
15715 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315716 MockWrite(
15717 "GET / HTTP/1.1\r\n"
15718 "Host: www.example.org\r\n"
15719 "Connection: keep-alive\r\n"
15720 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415721 };
15722 MockRead data_reads[] = {
15723 MockRead("HTTP/1.1 200 OK\r\n"
15724 "Content-Length: 5\r\n\r\n"
15725 "hello"),
15726 MockRead(ASYNC, ERR_UNEXPECTED),
15727 };
15728
15729 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15730 data_writes, arraysize(data_writes));
15731 session_deps_.socket_factory->AddSocketDataProvider(&data);
15732
15733 TestCompletionCallback callback;
15734
tfarina42834112016-09-22 13:38:2015735 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415737
15738 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115739 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415740
15741 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615742 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415743 std::string foo;
15744 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15745 EXPECT_EQ("bar", foo);
15746}
15747
[email protected]bf828982013-08-14 18:01:4715748namespace {
15749
yhiranoa7e05bb2014-11-06 05:40:3915750// Fake HttpStream that simply records calls to SetPriority().
15751class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315752 public base::SupportsWeakPtr<FakeStream> {
15753 public:
15754 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2715755 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0315756
15757 RequestPriority priority() const { return priority_; }
15758
dchengb03027d2014-10-21 12:00:2015759 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2715760 bool can_send_early,
dchengb03027d2014-10-21 12:00:2015761 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015762 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015763 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315764 return ERR_IO_PENDING;
15765 }
15766
dchengb03027d2014-10-21 12:00:2015767 int SendRequest(const HttpRequestHeaders& request_headers,
15768 HttpResponseInfo* response,
15769 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315770 ADD_FAILURE();
15771 return ERR_UNEXPECTED;
15772 }
15773
dchengb03027d2014-10-21 12:00:2015774 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315775 ADD_FAILURE();
15776 return ERR_UNEXPECTED;
15777 }
15778
dchengb03027d2014-10-21 12:00:2015779 int ReadResponseBody(IOBuffer* buf,
15780 int buf_len,
15781 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315782 ADD_FAILURE();
15783 return ERR_UNEXPECTED;
15784 }
15785
dchengb03027d2014-10-21 12:00:2015786 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315787
dchengb03027d2014-10-21 12:00:2015788 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315789 ADD_FAILURE();
15790 return false;
15791 }
15792
dchengb03027d2014-10-21 12:00:2015793 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315794 ADD_FAILURE();
15795 return false;
15796 }
15797
dchengb03027d2014-10-21 12:00:2015798 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315799
mmenkebd84c392015-09-02 14:12:3415800 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315801
sclittle4de1bab92015-09-22 21:28:2415802 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915803 ADD_FAILURE();
15804 return 0;
15805 }
15806
sclittlebe1ccf62015-09-02 19:40:3615807 int64_t GetTotalSentBytes() const override {
15808 ADD_FAILURE();
15809 return 0;
15810 }
15811
dchengb03027d2014-10-21 12:00:2015812 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315813 ADD_FAILURE();
15814 return false;
15815 }
15816
rchcd379012017-04-12 21:53:3215817 bool GetAlternativeService(
15818 AlternativeService* alternative_service) const override {
15819 ADD_FAILURE();
15820 return false;
15821 }
15822
dchengb03027d2014-10-21 12:00:2015823 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15824
15825 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315826 ADD_FAILURE();
15827 }
15828
ttuttled9dbc652015-09-29 20:00:5915829 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15830
nharper78e6d2b2016-09-21 05:42:3515831 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15832 TokenBindingType tb_type,
15833 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415834 ADD_FAILURE();
15835 return ERR_NOT_IMPLEMENTED;
15836 }
15837
dchengb03027d2014-10-21 12:00:2015838 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315839
zhongyica364fbb2015-12-12 03:39:1215840 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15841
dchengb03027d2014-10-21 12:00:2015842 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315843
yhiranoa7e05bb2014-11-06 05:40:3915844 HttpStream* RenewStreamForAuth() override { return NULL; }
15845
Andrey Kosyakov83a6eee2017-08-14 19:20:0415846 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15847
[email protected]e86839fd2013-08-14 18:29:0315848 private:
15849 RequestPriority priority_;
15850
15851 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15852};
15853
15854// Fake HttpStreamRequest that simply records calls to SetPriority()
15855// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715856class FakeStreamRequest : public HttpStreamRequest,
15857 public base::SupportsWeakPtr<FakeStreamRequest> {
15858 public:
[email protected]e86839fd2013-08-14 18:29:0315859 FakeStreamRequest(RequestPriority priority,
15860 HttpStreamRequest::Delegate* delegate)
15861 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415862 delegate_(delegate),
15863 websocket_stream_create_helper_(NULL) {}
15864
15865 FakeStreamRequest(RequestPriority priority,
15866 HttpStreamRequest::Delegate* delegate,
15867 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15868 : priority_(priority),
15869 delegate_(delegate),
15870 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315871
Chris Watkins7a41d3552017-12-01 02:13:2715872 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4715873
15874 RequestPriority priority() const { return priority_; }
15875
[email protected]831e4a32013-11-14 02:14:4415876 const WebSocketHandshakeStreamBase::CreateHelper*
15877 websocket_stream_create_helper() const {
15878 return websocket_stream_create_helper_;
15879 }
15880
[email protected]e86839fd2013-08-14 18:29:0315881 // Create a new FakeStream and pass it to the request's
15882 // delegate. Returns a weak pointer to the FakeStream.
15883 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915884 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315885 // Do this before calling OnStreamReady() as OnStreamReady() may
15886 // immediately delete |fake_stream|.
15887 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015888 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315889 return weak_stream;
15890 }
15891
asanka681f02d2017-02-22 17:06:3915892 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715893 ADD_FAILURE();
15894 return ERR_UNEXPECTED;
15895 }
15896
dchengb03027d2014-10-21 12:00:2015897 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715898 ADD_FAILURE();
15899 return LoadState();
15900 }
15901
dchengb03027d2014-10-21 12:00:2015902 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715903
bnc94c92842016-09-21 15:22:5215904 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715905
bnc6227b26e2016-08-12 02:00:4315906 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715907
dchengb03027d2014-10-21 12:00:2015908 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715909
ttuttle1f2d7e92015-04-28 16:17:4715910 const ConnectionAttempts& connection_attempts() const override {
15911 static ConnectionAttempts no_attempts;
15912 return no_attempts;
15913 }
15914
[email protected]bf828982013-08-14 18:01:4715915 private:
15916 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315917 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415918 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715919
15920 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15921};
15922
15923// Fake HttpStreamFactory that vends FakeStreamRequests.
15924class FakeStreamFactory : public HttpStreamFactory {
15925 public:
Chris Watkins7a41d3552017-12-01 02:13:2715926 FakeStreamFactory() = default;
15927 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4715928
15929 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15930 // RequestStream() (which may be NULL if it was destroyed already).
15931 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15932 return last_stream_request_;
15933 }
15934
xunjieli96f2a402017-06-05 17:24:2715935 std::unique_ptr<HttpStreamRequest> RequestStream(
15936 const HttpRequestInfo& info,
15937 RequestPriority priority,
15938 const SSLConfig& server_ssl_config,
15939 const SSLConfig& proxy_ssl_config,
15940 HttpStreamRequest::Delegate* delegate,
15941 bool enable_ip_based_pooling,
15942 bool enable_alternative_services,
15943 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915944 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715945 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715946 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715947 }
15948
xunjieli96f2a402017-06-05 17:24:2715949 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815950 const HttpRequestInfo& info,
15951 RequestPriority priority,
15952 const SSLConfig& server_ssl_config,
15953 const SSLConfig& proxy_ssl_config,
15954 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915955 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615956 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015957 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815958 NOTREACHED();
15959 return nullptr;
15960 }
15961
xunjieli96f2a402017-06-05 17:24:2715962 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715963 const HttpRequestInfo& info,
15964 RequestPriority priority,
15965 const SSLConfig& server_ssl_config,
15966 const SSLConfig& proxy_ssl_config,
15967 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615968 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915969 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615970 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015971 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715972 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915973 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415974 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715975 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715976 }
15977
dchengb03027d2014-10-21 12:00:2015978 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915979 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715980 ADD_FAILURE();
15981 }
15982
dchengb03027d2014-10-21 12:00:2015983 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715984 ADD_FAILURE();
15985 return NULL;
15986 }
15987
xunjielif5267de2017-01-20 21:18:5715988 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15989 const std::string& parent_absolute_name) const override {
15990 ADD_FAILURE();
15991 }
15992
[email protected]bf828982013-08-14 18:01:4715993 private:
15994 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15995
15996 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15997};
15998
[email protected]bf828982013-08-14 18:01:4715999} // namespace
16000
16001// Make sure that HttpNetworkTransaction passes on its priority to its
16002// stream request on start.
bncd16676a2016-07-20 16:23:0116003TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916004 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216005 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716006 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916007 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716008
krasinc06a72a2016-12-21 03:42:4616009 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116010 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716011
wezca1070932016-05-26 20:30:5216012 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716013
[email protected]bf828982013-08-14 18:01:4716014 TestCompletionCallback callback;
16015 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016016 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716017
16018 base::WeakPtr<FakeStreamRequest> fake_request =
16019 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216020 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716021 EXPECT_EQ(LOW, fake_request->priority());
16022}
16023
16024// Make sure that HttpNetworkTransaction passes on its priority
16025// updates to its stream request.
bncd16676a2016-07-20 16:23:0116026TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216028 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716029 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916030 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716031
krasinc06a72a2016-12-21 03:42:4616032 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116033 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716034
[email protected]bf828982013-08-14 18:01:4716035 TestCompletionCallback callback;
16036 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016037 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716038
16039 base::WeakPtr<FakeStreamRequest> fake_request =
16040 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216041 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716042 EXPECT_EQ(LOW, fake_request->priority());
16043
16044 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216045 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716046 EXPECT_EQ(LOWEST, fake_request->priority());
16047}
16048
[email protected]e86839fd2013-08-14 18:29:0316049// Make sure that HttpNetworkTransaction passes on its priority
16050// updates to its stream.
bncd16676a2016-07-20 16:23:0116051TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916052 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216053 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316054 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916055 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316056
krasinc06a72a2016-12-21 03:42:4616057 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116058 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316059
[email protected]e86839fd2013-08-14 18:29:0316060 TestCompletionCallback callback;
16061 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016062 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316063
16064 base::WeakPtr<FakeStreamRequest> fake_request =
16065 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216066 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316067 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216068 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316069 EXPECT_EQ(LOW, fake_stream->priority());
16070
16071 trans.SetPriority(LOWEST);
16072 EXPECT_EQ(LOWEST, fake_stream->priority());
16073}
16074
[email protected]043b68c82013-08-22 23:41:5216075// Tests that when a used socket is returned to the SSL socket pool, it's closed
16076// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116077TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216078 ClientSocketPoolManager::set_max_sockets_per_group(
16079 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16080 ClientSocketPoolManager::set_max_sockets_per_pool(
16081 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16082
16083 // Set up SSL request.
16084
16085 HttpRequestInfo ssl_request;
16086 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316087 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216088
16089 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316090 MockWrite(
16091 "GET / HTTP/1.1\r\n"
16092 "Host: www.example.org\r\n"
16093 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216094 };
16095 MockRead ssl_reads[] = {
16096 MockRead("HTTP/1.1 200 OK\r\n"),
16097 MockRead("Content-Length: 11\r\n\r\n"),
16098 MockRead("hello world"),
16099 MockRead(SYNCHRONOUS, OK),
16100 };
16101 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16102 ssl_writes, arraysize(ssl_writes));
16103 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16104
16105 SSLSocketDataProvider ssl(ASYNC, OK);
16106 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16107
16108 // Set up HTTP request.
16109
16110 HttpRequestInfo http_request;
16111 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316112 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216113
16114 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316115 MockWrite(
16116 "GET / HTTP/1.1\r\n"
16117 "Host: www.example.org\r\n"
16118 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216119 };
16120 MockRead http_reads[] = {
16121 MockRead("HTTP/1.1 200 OK\r\n"),
16122 MockRead("Content-Length: 7\r\n\r\n"),
16123 MockRead("falafel"),
16124 MockRead(SYNCHRONOUS, OK),
16125 };
16126 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16127 http_writes, arraysize(http_writes));
16128 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16129
danakj1fd259a02016-04-16 03:17:0916130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216131
16132 // Start the SSL request.
16133 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616134 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016135 ASSERT_EQ(ERR_IO_PENDING,
16136 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16137 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216138
16139 // Start the HTTP request. Pool should stall.
16140 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616141 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016142 ASSERT_EQ(ERR_IO_PENDING,
16143 http_trans.Start(&http_request, http_callback.callback(),
16144 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116145 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216146
16147 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116148 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216149 std::string response_data;
bnc691fda62016-08-12 00:43:1616150 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216151 EXPECT_EQ("hello world", response_data);
16152
16153 // The SSL socket should automatically be closed, so the HTTP request can
16154 // start.
dcheng48459ac22014-08-26 00:46:4116155 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16156 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216157
16158 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116159 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616160 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216161 EXPECT_EQ("falafel", response_data);
16162
dcheng48459ac22014-08-26 00:46:4116163 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216164}
16165
16166// Tests that when a SSL connection is established but there's no corresponding
16167// request that needs it, the new socket is closed if the transport socket pool
16168// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116169TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216170 ClientSocketPoolManager::set_max_sockets_per_group(
16171 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16172 ClientSocketPoolManager::set_max_sockets_per_pool(
16173 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16174
16175 // Set up an ssl request.
16176
16177 HttpRequestInfo ssl_request;
16178 ssl_request.method = "GET";
16179 ssl_request.url = GURL("https://www.foopy.com/");
16180
16181 // No data will be sent on the SSL socket.
16182 StaticSocketDataProvider ssl_data;
16183 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16184
16185 SSLSocketDataProvider ssl(ASYNC, OK);
16186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16187
16188 // Set up HTTP request.
16189
16190 HttpRequestInfo http_request;
16191 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316192 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216193
16194 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316195 MockWrite(
16196 "GET / HTTP/1.1\r\n"
16197 "Host: www.example.org\r\n"
16198 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216199 };
16200 MockRead http_reads[] = {
16201 MockRead("HTTP/1.1 200 OK\r\n"),
16202 MockRead("Content-Length: 7\r\n\r\n"),
16203 MockRead("falafel"),
16204 MockRead(SYNCHRONOUS, OK),
16205 };
16206 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16207 http_writes, arraysize(http_writes));
16208 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16209
danakj1fd259a02016-04-16 03:17:0916210 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216211
16212 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16213 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916214 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916215 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116216 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216217
16218 // Start the HTTP request. Pool should stall.
16219 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616220 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016221 ASSERT_EQ(ERR_IO_PENDING,
16222 http_trans.Start(&http_request, http_callback.callback(),
16223 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116224 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216225
16226 // The SSL connection will automatically be closed once the connection is
16227 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116228 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216229 std::string response_data;
bnc691fda62016-08-12 00:43:1616230 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216231 EXPECT_EQ("falafel", response_data);
16232
dcheng48459ac22014-08-26 00:46:4116233 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216234}
16235
bncd16676a2016-07-20 16:23:0116236TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916237 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216238 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916239 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216240 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416241
16242 HttpRequestInfo request;
16243 request.method = "POST";
16244 request.url = GURL("http://www.foo.com/");
16245 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416246
danakj1fd259a02016-04-16 03:17:0916247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616248 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416249 // Send headers successfully, but get an error while sending the body.
16250 MockWrite data_writes[] = {
16251 MockWrite("POST / HTTP/1.1\r\n"
16252 "Host: www.foo.com\r\n"
16253 "Connection: keep-alive\r\n"
16254 "Content-Length: 3\r\n\r\n"),
16255 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16256 };
16257
16258 MockRead data_reads[] = {
16259 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16260 MockRead("hello world"),
16261 MockRead(SYNCHRONOUS, OK),
16262 };
16263 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16264 arraysize(data_writes));
16265 session_deps_.socket_factory->AddSocketDataProvider(&data);
16266
16267 TestCompletionCallback callback;
16268
tfarina42834112016-09-22 13:38:2016269 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416271
16272 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116273 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416274
bnc691fda62016-08-12 00:43:1616275 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216276 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416277
wezca1070932016-05-26 20:30:5216278 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416279 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16280
16281 std::string response_data;
bnc691fda62016-08-12 00:43:1616282 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116283 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416284 EXPECT_EQ("hello world", response_data);
16285}
16286
16287// This test makes sure the retry logic doesn't trigger when reading an error
16288// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116289TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416290 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416292 MockWrite data_writes[] = {
16293 MockWrite("GET / HTTP/1.1\r\n"
16294 "Host: www.foo.com\r\n"
16295 "Connection: keep-alive\r\n\r\n"),
16296 MockWrite("POST / HTTP/1.1\r\n"
16297 "Host: www.foo.com\r\n"
16298 "Connection: keep-alive\r\n"
16299 "Content-Length: 3\r\n\r\n"),
16300 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16301 };
16302
16303 MockRead data_reads[] = {
16304 MockRead("HTTP/1.1 200 Peachy\r\n"
16305 "Content-Length: 14\r\n\r\n"),
16306 MockRead("first response"),
16307 MockRead("HTTP/1.1 400 Not OK\r\n"
16308 "Content-Length: 15\r\n\r\n"),
16309 MockRead("second response"),
16310 MockRead(SYNCHRONOUS, OK),
16311 };
16312 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16313 arraysize(data_writes));
16314 session_deps_.socket_factory->AddSocketDataProvider(&data);
16315
16316 TestCompletionCallback callback;
16317 HttpRequestInfo request1;
16318 request1.method = "GET";
16319 request1.url = GURL("http://www.foo.com/");
16320 request1.load_flags = 0;
16321
bnc87dcefc2017-05-25 12:47:5816322 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916323 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016324 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416326
16327 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116328 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416329
16330 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216331 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416332
wezca1070932016-05-26 20:30:5216333 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416334 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16335
16336 std::string response_data1;
16337 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116338 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416339 EXPECT_EQ("first response", response_data1);
16340 // Delete the transaction to release the socket back into the socket pool.
16341 trans1.reset();
16342
danakj1fd259a02016-04-16 03:17:0916343 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216344 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916345 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216346 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416347
16348 HttpRequestInfo request2;
16349 request2.method = "POST";
16350 request2.url = GURL("http://www.foo.com/");
16351 request2.upload_data_stream = &upload_data_stream;
16352 request2.load_flags = 0;
16353
bnc691fda62016-08-12 00:43:1616354 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016355 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416357
16358 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116359 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416360
bnc691fda62016-08-12 00:43:1616361 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216362 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416363
wezca1070932016-05-26 20:30:5216364 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416365 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16366
16367 std::string response_data2;
bnc691fda62016-08-12 00:43:1616368 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116369 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416370 EXPECT_EQ("second response", response_data2);
16371}
16372
bncd16676a2016-07-20 16:23:0116373TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416374 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916375 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216376 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916377 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216378 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416379
16380 HttpRequestInfo request;
16381 request.method = "POST";
16382 request.url = GURL("http://www.foo.com/");
16383 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416384
danakj1fd259a02016-04-16 03:17:0916385 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616386 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416387 // Send headers successfully, but get an error while sending the body.
16388 MockWrite data_writes[] = {
16389 MockWrite("POST / HTTP/1.1\r\n"
16390 "Host: www.foo.com\r\n"
16391 "Connection: keep-alive\r\n"
16392 "Content-Length: 3\r\n\r\n"
16393 "fo"),
16394 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16395 };
16396
16397 MockRead data_reads[] = {
16398 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16399 MockRead("hello world"),
16400 MockRead(SYNCHRONOUS, OK),
16401 };
16402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16403 arraysize(data_writes));
16404 session_deps_.socket_factory->AddSocketDataProvider(&data);
16405
16406 TestCompletionCallback callback;
16407
tfarina42834112016-09-22 13:38:2016408 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416410
16411 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116412 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416413
bnc691fda62016-08-12 00:43:1616414 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216415 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416416
wezca1070932016-05-26 20:30:5216417 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416418 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16419
16420 std::string response_data;
bnc691fda62016-08-12 00:43:1616421 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116422 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416423 EXPECT_EQ("hello world", response_data);
16424}
16425
16426// This tests the more common case than the previous test, where headers and
16427// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116428TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716429 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416430
16431 HttpRequestInfo request;
16432 request.method = "POST";
16433 request.url = GURL("http://www.foo.com/");
16434 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416435
danakj1fd259a02016-04-16 03:17:0916436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416438 // Send headers successfully, but get an error while sending the body.
16439 MockWrite data_writes[] = {
16440 MockWrite("POST / HTTP/1.1\r\n"
16441 "Host: www.foo.com\r\n"
16442 "Connection: keep-alive\r\n"
16443 "Transfer-Encoding: chunked\r\n\r\n"),
16444 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16445 };
16446
16447 MockRead data_reads[] = {
16448 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16449 MockRead("hello world"),
16450 MockRead(SYNCHRONOUS, OK),
16451 };
16452 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16453 arraysize(data_writes));
16454 session_deps_.socket_factory->AddSocketDataProvider(&data);
16455
16456 TestCompletionCallback callback;
16457
tfarina42834112016-09-22 13:38:2016458 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416460 // Make sure the headers are sent before adding a chunk. This ensures that
16461 // they can't be merged with the body in a single send. Not currently
16462 // necessary since a chunked body is never merged with headers, but this makes
16463 // the test more future proof.
16464 base::RunLoop().RunUntilIdle();
16465
mmenkecbc2b712014-10-09 20:29:0716466 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416467
16468 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116469 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416470
bnc691fda62016-08-12 00:43:1616471 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216472 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416473
wezca1070932016-05-26 20:30:5216474 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416475 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16476
16477 std::string response_data;
bnc691fda62016-08-12 00:43:1616478 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116479 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416480 EXPECT_EQ("hello world", response_data);
16481}
16482
bncd16676a2016-07-20 16:23:0116483TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916484 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216485 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916486 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216487 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416488
16489 HttpRequestInfo request;
16490 request.method = "POST";
16491 request.url = GURL("http://www.foo.com/");
16492 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416493
danakj1fd259a02016-04-16 03:17:0916494 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616495 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416496
16497 MockWrite data_writes[] = {
16498 MockWrite("POST / HTTP/1.1\r\n"
16499 "Host: www.foo.com\r\n"
16500 "Connection: keep-alive\r\n"
16501 "Content-Length: 3\r\n\r\n"),
16502 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16503 };
16504
16505 MockRead data_reads[] = {
16506 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16507 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16508 MockRead("hello world"),
16509 MockRead(SYNCHRONOUS, OK),
16510 };
16511 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16512 arraysize(data_writes));
16513 session_deps_.socket_factory->AddSocketDataProvider(&data);
16514
16515 TestCompletionCallback callback;
16516
tfarina42834112016-09-22 13:38:2016517 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416519
16520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116521 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416522
bnc691fda62016-08-12 00:43:1616523 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216524 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416525
wezca1070932016-05-26 20:30:5216526 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416527 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16528
16529 std::string response_data;
bnc691fda62016-08-12 00:43:1616530 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116531 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416532 EXPECT_EQ("hello world", response_data);
16533}
16534
bncd16676a2016-07-20 16:23:0116535TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916536 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216537 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916538 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216539 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416540
16541 HttpRequestInfo request;
16542 request.method = "POST";
16543 request.url = GURL("http://www.foo.com/");
16544 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416545
danakj1fd259a02016-04-16 03:17:0916546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416548 // Send headers successfully, but get an error while sending the body.
16549 MockWrite data_writes[] = {
16550 MockWrite("POST / HTTP/1.1\r\n"
16551 "Host: www.foo.com\r\n"
16552 "Connection: keep-alive\r\n"
16553 "Content-Length: 3\r\n\r\n"),
16554 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16555 };
16556
16557 MockRead data_reads[] = {
16558 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16559 MockRead("hello world"),
16560 MockRead(SYNCHRONOUS, OK),
16561 };
16562 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16563 arraysize(data_writes));
16564 session_deps_.socket_factory->AddSocketDataProvider(&data);
16565
16566 TestCompletionCallback callback;
16567
tfarina42834112016-09-22 13:38:2016568 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116569 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416570
16571 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116572 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416573}
16574
bncd16676a2016-07-20 16:23:0116575TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416576 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916577 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216578 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916579 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216580 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416581
16582 HttpRequestInfo request;
16583 request.method = "POST";
16584 request.url = GURL("http://www.foo.com/");
16585 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416586
danakj1fd259a02016-04-16 03:17:0916587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616588 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416589 // Send headers successfully, but get an error while sending the body.
16590 MockWrite data_writes[] = {
16591 MockWrite("POST / HTTP/1.1\r\n"
16592 "Host: www.foo.com\r\n"
16593 "Connection: keep-alive\r\n"
16594 "Content-Length: 3\r\n\r\n"),
16595 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16596 };
16597
16598 MockRead data_reads[] = {
16599 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16600 MockRead("HTTP/1.0 302 Redirect\r\n"),
16601 MockRead("Location: http://somewhere-else.com/\r\n"),
16602 MockRead("Content-Length: 0\r\n\r\n"),
16603 MockRead(SYNCHRONOUS, OK),
16604 };
16605 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16606 arraysize(data_writes));
16607 session_deps_.socket_factory->AddSocketDataProvider(&data);
16608
16609 TestCompletionCallback callback;
16610
tfarina42834112016-09-22 13:38:2016611 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416613
16614 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116615 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416616}
16617
bncd16676a2016-07-20 16:23:0116618TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916619 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216620 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916621 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216622 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416623
16624 HttpRequestInfo request;
16625 request.method = "POST";
16626 request.url = GURL("http://www.foo.com/");
16627 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416628
danakj1fd259a02016-04-16 03:17:0916629 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416631 // Send headers successfully, but get an error while sending the body.
16632 MockWrite data_writes[] = {
16633 MockWrite("POST / HTTP/1.1\r\n"
16634 "Host: www.foo.com\r\n"
16635 "Connection: keep-alive\r\n"
16636 "Content-Length: 3\r\n\r\n"),
16637 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16638 };
16639
16640 MockRead data_reads[] = {
16641 MockRead("HTTP 0.9 rocks!"),
16642 MockRead(SYNCHRONOUS, OK),
16643 };
16644 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16645 arraysize(data_writes));
16646 session_deps_.socket_factory->AddSocketDataProvider(&data);
16647
16648 TestCompletionCallback callback;
16649
tfarina42834112016-09-22 13:38:2016650 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416652
16653 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116654 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416655}
16656
bncd16676a2016-07-20 16:23:0116657TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916658 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216659 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916660 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216661 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416662
16663 HttpRequestInfo request;
16664 request.method = "POST";
16665 request.url = GURL("http://www.foo.com/");
16666 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416667
danakj1fd259a02016-04-16 03:17:0916668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416670 // Send headers successfully, but get an error while sending the body.
16671 MockWrite data_writes[] = {
16672 MockWrite("POST / HTTP/1.1\r\n"
16673 "Host: www.foo.com\r\n"
16674 "Connection: keep-alive\r\n"
16675 "Content-Length: 3\r\n\r\n"),
16676 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16677 };
16678
16679 MockRead data_reads[] = {
16680 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16681 MockRead(SYNCHRONOUS, OK),
16682 };
16683 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16684 arraysize(data_writes));
16685 session_deps_.socket_factory->AddSocketDataProvider(&data);
16686
16687 TestCompletionCallback callback;
16688
tfarina42834112016-09-22 13:38:2016689 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416691
16692 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116693 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416694}
16695
Bence Békydca6bd92018-01-30 13:43:0616696#if BUILDFLAG(ENABLE_WEBSOCKETS)
16697
16698namespace {
16699
16700void AddWebSocketHeaders(HttpRequestHeaders* headers) {
16701 headers->SetHeader("Connection", "Upgrade");
16702 headers->SetHeader("Upgrade", "websocket");
16703 headers->SetHeader("Origin", "http://www.example.org");
16704 headers->SetHeader("Sec-WebSocket-Version", "13");
16705 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
16706}
16707
16708} // namespace
16709
16710TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
16711 // The same logic needs to be tested for both ws: and wss: schemes, but this
16712 // test is already parameterised on NextProto, so it uses a loop to verify
16713 // that the different schemes work.
16714 std::string test_cases[] = {"ws://www.example.org/",
16715 "wss://www.example.org/"};
16716 for (size_t i = 0; i < arraysize(test_cases); ++i) {
16717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16718 HttpNetworkSessionPeer peer(session.get());
16719 FakeStreamFactory* fake_factory = new FakeStreamFactory();
16720 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
16721
16722 HttpRequestInfo request;
16723 request.method = "GET";
16724 request.url = GURL(test_cases[i]);
16725
16726 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16727 HttpNetworkTransaction trans(LOW, session.get());
16728 trans.SetWebSocketHandshakeStreamCreateHelper(
16729 &websocket_stream_create_helper);
16730
16731 TestCompletionCallback callback;
16732 EXPECT_EQ(ERR_IO_PENDING,
16733 trans.Start(&request, callback.callback(), NetLogWithSource()));
16734
16735 base::WeakPtr<FakeStreamRequest> fake_request =
16736 fake_factory->last_stream_request();
16737 ASSERT_TRUE(fake_request);
16738 EXPECT_EQ(&websocket_stream_create_helper,
16739 fake_request->websocket_stream_create_helper());
16740 }
16741}
16742
Adam Rice425cf122015-01-19 06:18:2416743// Verify that proxy headers are not sent to the destination server when
16744// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116745TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416746 HttpRequestInfo request;
16747 request.method = "GET";
bncce36dca22015-04-21 22:11:2316748 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416749 AddWebSocketHeaders(&request.extra_headers);
16750
16751 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916752 session_deps_.proxy_resolution_service =
16753 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416754
danakj1fd259a02016-04-16 03:17:0916755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416756
16757 // Since a proxy is configured, try to establish a tunnel.
16758 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716759 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16760 "Host: www.example.org:443\r\n"
16761 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416762
16763 // After calling trans->RestartWithAuth(), this is the request we should
16764 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716765 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16766 "Host: www.example.org:443\r\n"
16767 "Proxy-Connection: keep-alive\r\n"
16768 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416769
rsleevidb16bb02015-11-12 23:47:1716770 MockWrite("GET / HTTP/1.1\r\n"
16771 "Host: www.example.org\r\n"
16772 "Connection: Upgrade\r\n"
16773 "Upgrade: websocket\r\n"
16774 "Origin: http://www.example.org\r\n"
16775 "Sec-WebSocket-Version: 13\r\n"
16776 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416777 };
16778
16779 // The proxy responds to the connect with a 407, using a persistent
16780 // connection.
16781 MockRead data_reads[] = {
16782 // No credentials.
16783 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16784 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416785 MockRead("Content-Length: 0\r\n"),
16786 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416787
16788 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16789
16790 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16791 MockRead("Upgrade: websocket\r\n"),
16792 MockRead("Connection: Upgrade\r\n"),
16793 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16794 };
16795
16796 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16797 arraysize(data_writes));
16798 session_deps_.socket_factory->AddSocketDataProvider(&data);
16799 SSLSocketDataProvider ssl(ASYNC, OK);
16800 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16801
bnc87dcefc2017-05-25 12:47:5816802 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916803 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416804 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16805 trans->SetWebSocketHandshakeStreamCreateHelper(
16806 &websocket_stream_create_helper);
16807
16808 {
16809 TestCompletionCallback callback;
16810
tfarina42834112016-09-22 13:38:2016811 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416813
16814 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116815 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416816 }
16817
16818 const HttpResponseInfo* response = trans->GetResponseInfo();
16819 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216820 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416821 EXPECT_EQ(407, response->headers->response_code());
16822
16823 {
16824 TestCompletionCallback callback;
16825
16826 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16827 callback.callback());
robpercival214763f2016-07-01 23:27:0116828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416829
16830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116831 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416832 }
16833
16834 response = trans->GetResponseInfo();
16835 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216836 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416837
16838 EXPECT_EQ(101, response->headers->response_code());
16839
16840 trans.reset();
16841 session->CloseAllConnections();
16842}
16843
16844// Verify that proxy headers are not sent to the destination server when
16845// establishing a tunnel for an insecure WebSocket connection.
16846// This requires the authentication info to be injected into the auth cache
16847// due to crbug.com/395064
16848// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116849TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416850 HttpRequestInfo request;
16851 request.method = "GET";
bncce36dca22015-04-21 22:11:2316852 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416853 AddWebSocketHeaders(&request.extra_headers);
16854
16855 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916856 session_deps_.proxy_resolution_service =
16857 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416858
danakj1fd259a02016-04-16 03:17:0916859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416860
16861 MockWrite data_writes[] = {
16862 // Try to establish a tunnel for the WebSocket connection, with
16863 // credentials. Because WebSockets have a separate set of socket pools,
16864 // they cannot and will not use the same TCP/IP connection as the
16865 // preflight HTTP request.
16866 MockWrite(
bncce36dca22015-04-21 22:11:2316867 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16868 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416869 "Proxy-Connection: keep-alive\r\n"
16870 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16871
16872 MockWrite(
16873 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316874 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416875 "Connection: Upgrade\r\n"
16876 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316877 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416878 "Sec-WebSocket-Version: 13\r\n"
16879 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16880 };
16881
16882 MockRead data_reads[] = {
16883 // HTTP CONNECT with credentials.
16884 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16885
16886 // WebSocket connection established inside tunnel.
16887 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16888 MockRead("Upgrade: websocket\r\n"),
16889 MockRead("Connection: Upgrade\r\n"),
16890 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16891 };
16892
16893 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16894 arraysize(data_writes));
16895 session_deps_.socket_factory->AddSocketDataProvider(&data);
16896
16897 session->http_auth_cache()->Add(
16898 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16899 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16900
bnc87dcefc2017-05-25 12:47:5816901 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916902 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416903 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16904 trans->SetWebSocketHandshakeStreamCreateHelper(
16905 &websocket_stream_create_helper);
16906
16907 TestCompletionCallback callback;
16908
tfarina42834112016-09-22 13:38:2016909 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416911
16912 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116913 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416914
16915 const HttpResponseInfo* response = trans->GetResponseInfo();
16916 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216917 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416918
16919 EXPECT_EQ(101, response->headers->response_code());
16920
16921 trans.reset();
16922 session->CloseAllConnections();
16923}
16924
Bence Békydca6bd92018-01-30 13:43:0616925#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
16926
bncd16676a2016-07-20 16:23:0116927TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916928 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216929 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916930 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216931 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216932
16933 HttpRequestInfo request;
16934 request.method = "POST";
16935 request.url = GURL("http://www.foo.com/");
16936 request.upload_data_stream = &upload_data_stream;
16937
danakj1fd259a02016-04-16 03:17:0916938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216940 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("foo"),
16946 };
16947
16948 MockRead data_reads[] = {
16949 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16950 MockRead(SYNCHRONOUS, OK),
16951 };
16952 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16953 arraysize(data_writes));
16954 session_deps_.socket_factory->AddSocketDataProvider(&data);
16955
16956 TestCompletionCallback callback;
16957
16958 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016959 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116960 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216961
16962 std::string response_data;
bnc691fda62016-08-12 00:43:1616963 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216964
16965 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616966 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216967 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616968 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216969}
16970
bncd16676a2016-07-20 16:23:0116971TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916972 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216973 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916974 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216975 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216976
16977 HttpRequestInfo request;
16978 request.method = "POST";
16979 request.url = GURL("http://www.foo.com/");
16980 request.upload_data_stream = &upload_data_stream;
16981
danakj1fd259a02016-04-16 03:17:0916982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216984 MockWrite data_writes[] = {
16985 MockWrite("POST / HTTP/1.1\r\n"
16986 "Host: www.foo.com\r\n"
16987 "Connection: keep-alive\r\n"
16988 "Content-Length: 3\r\n\r\n"),
16989 MockWrite("foo"),
16990 };
16991
16992 MockRead data_reads[] = {
16993 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16994 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16995 MockRead(SYNCHRONOUS, OK),
16996 };
16997 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16998 arraysize(data_writes));
16999 session_deps_.socket_factory->AddSocketDataProvider(&data);
17000
17001 TestCompletionCallback callback;
17002
17003 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017004 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117005 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217006
17007 std::string response_data;
bnc691fda62016-08-12 00:43:1617008 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217009
17010 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617011 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217012 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617013 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217014}
17015
bncd16676a2016-07-20 16:23:0117016TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217017 ChunkedUploadDataStream upload_data_stream(0);
17018
17019 HttpRequestInfo request;
17020 request.method = "POST";
17021 request.url = GURL("http://www.foo.com/");
17022 request.upload_data_stream = &upload_data_stream;
17023
danakj1fd259a02016-04-16 03:17:0917024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617025 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217026 // Send headers successfully, but get an error while sending the body.
17027 MockWrite data_writes[] = {
17028 MockWrite("POST / HTTP/1.1\r\n"
17029 "Host: www.foo.com\r\n"
17030 "Connection: keep-alive\r\n"
17031 "Transfer-Encoding: chunked\r\n\r\n"),
17032 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17033 };
17034
17035 MockRead data_reads[] = {
17036 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17037 MockRead(SYNCHRONOUS, OK),
17038 };
17039 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17040 arraysize(data_writes));
17041 session_deps_.socket_factory->AddSocketDataProvider(&data);
17042
17043 TestCompletionCallback callback;
17044
17045 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017046 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217047
17048 base::RunLoop().RunUntilIdle();
17049 upload_data_stream.AppendData("f", 1, false);
17050
17051 base::RunLoop().RunUntilIdle();
17052 upload_data_stream.AppendData("oo", 2, true);
17053
robpercival214763f2016-07-01 23:27:0117054 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217055
17056 std::string response_data;
bnc691fda62016-08-12 00:43:1617057 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217058
17059 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617060 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217061 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617062 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217063}
17064
rdsmith1d343be52016-10-21 20:37:5017065// Confirm that transactions whose throttle is created in (and stays in)
17066// the unthrottled state are not blocked.
17067TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17068 TestNetworkStreamThrottler* throttler(nullptr);
17069 std::unique_ptr<HttpNetworkSession> session(
17070 CreateSessionWithThrottler(&session_deps_, &throttler));
17071
17072 // Send a simple request and make sure it goes through.
17073 HttpRequestInfo request;
17074 request.method = "GET";
17075 request.url = GURL("http://www.example.org/");
17076
bnc87dcefc2017-05-25 12:47:5817077 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917078 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017079
17080 MockWrite data_writes[] = {
17081 MockWrite("GET / HTTP/1.1\r\n"
17082 "Host: www.example.org\r\n"
17083 "Connection: keep-alive\r\n\r\n"),
17084 };
17085 MockRead data_reads[] = {
17086 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17087 MockRead(SYNCHRONOUS, OK),
17088 };
17089 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17090 arraysize(data_writes));
17091 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17092
17093 TestCompletionCallback callback;
17094 trans->Start(&request, callback.callback(), NetLogWithSource());
17095 EXPECT_EQ(OK, callback.WaitForResult());
17096}
17097
17098// Confirm requests can be blocked by a throttler, and are resumed
17099// when the throttle is unblocked.
17100TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17101 TestNetworkStreamThrottler* throttler(nullptr);
17102 std::unique_ptr<HttpNetworkSession> session(
17103 CreateSessionWithThrottler(&session_deps_, &throttler));
17104
17105 // Send a simple request and make sure it goes through.
17106 HttpRequestInfo request;
17107 request.method = "GET";
17108 request.url = GURL("http://www.example.org/");
17109
17110 MockWrite data_writes[] = {
17111 MockWrite("GET / HTTP/1.1\r\n"
17112 "Host: www.example.org\r\n"
17113 "Connection: keep-alive\r\n\r\n"),
17114 };
17115 MockRead data_reads[] = {
17116 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17117 MockRead(SYNCHRONOUS, OK),
17118 };
17119 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17120 arraysize(data_writes));
17121 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17122
17123 // Start a request that will be throttled at start; confirm it
17124 // doesn't complete.
17125 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817126 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917127 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017128
17129 TestCompletionCallback callback;
17130 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17131 EXPECT_EQ(ERR_IO_PENDING, rv);
17132
17133 base::RunLoop().RunUntilIdle();
17134 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17135 EXPECT_FALSE(callback.have_result());
17136
17137 // Confirm the request goes on to complete when unthrottled.
17138 throttler->UnthrottleAllRequests();
17139 base::RunLoop().RunUntilIdle();
17140 ASSERT_TRUE(callback.have_result());
17141 EXPECT_EQ(OK, callback.WaitForResult());
17142}
17143
17144// Destroy a request while it's throttled.
17145TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17146 TestNetworkStreamThrottler* throttler(nullptr);
17147 std::unique_ptr<HttpNetworkSession> session(
17148 CreateSessionWithThrottler(&session_deps_, &throttler));
17149
17150 // Send a simple request and make sure it goes through.
17151 HttpRequestInfo request;
17152 request.method = "GET";
17153 request.url = GURL("http://www.example.org/");
17154
17155 MockWrite data_writes[] = {
17156 MockWrite("GET / HTTP/1.1\r\n"
17157 "Host: www.example.org\r\n"
17158 "Connection: keep-alive\r\n\r\n"),
17159 };
17160 MockRead data_reads[] = {
17161 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17162 MockRead(SYNCHRONOUS, OK),
17163 };
17164 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17165 arraysize(data_writes));
17166 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17167
17168 // Start a request that will be throttled at start; confirm it
17169 // doesn't complete.
17170 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817171 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917172 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017173
17174 TestCompletionCallback callback;
17175 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17176 EXPECT_EQ(ERR_IO_PENDING, rv);
17177
17178 base::RunLoop().RunUntilIdle();
17179 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17180 EXPECT_FALSE(callback.have_result());
17181
17182 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17183 trans.reset();
17184 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17185}
17186
17187// Confirm the throttler receives SetPriority calls.
17188TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17189 TestNetworkStreamThrottler* throttler(nullptr);
17190 std::unique_ptr<HttpNetworkSession> session(
17191 CreateSessionWithThrottler(&session_deps_, &throttler));
17192
17193 // Send a simple request and make sure it goes through.
17194 HttpRequestInfo request;
17195 request.method = "GET";
17196 request.url = GURL("http://www.example.org/");
17197
17198 MockWrite data_writes[] = {
17199 MockWrite("GET / HTTP/1.1\r\n"
17200 "Host: www.example.org\r\n"
17201 "Connection: keep-alive\r\n\r\n"),
17202 };
17203 MockRead data_reads[] = {
17204 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17205 MockRead(SYNCHRONOUS, OK),
17206 };
17207 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17208 arraysize(data_writes));
17209 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17210
17211 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917212 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017213 // Start the transaction to associate a throttle with it.
17214 TestCompletionCallback callback;
17215 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17216 EXPECT_EQ(ERR_IO_PENDING, rv);
17217
17218 EXPECT_EQ(0, throttler->num_set_priority_calls());
17219 trans->SetPriority(LOW);
17220 EXPECT_EQ(1, throttler->num_set_priority_calls());
17221 EXPECT_EQ(LOW, throttler->last_priority_set());
17222
17223 throttler->UnthrottleAllRequests();
17224 base::RunLoop().RunUntilIdle();
17225 ASSERT_TRUE(callback.have_result());
17226 EXPECT_EQ(OK, callback.WaitForResult());
17227}
17228
17229// Confirm that unthrottling from a SetPriority call by the
17230// throttler works properly.
17231TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17232 TestNetworkStreamThrottler* throttler(nullptr);
17233 std::unique_ptr<HttpNetworkSession> session(
17234 CreateSessionWithThrottler(&session_deps_, &throttler));
17235
17236 // Send a simple request and make sure it goes through.
17237 HttpRequestInfo request;
17238 request.method = "GET";
17239 request.url = GURL("http://www.example.org/");
17240
17241 MockWrite data_writes[] = {
17242 MockWrite("GET / HTTP/1.1\r\n"
17243 "Host: www.example.org\r\n"
17244 "Connection: keep-alive\r\n\r\n"),
17245 };
17246 MockRead data_reads[] = {
17247 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17248 MockRead(SYNCHRONOUS, OK),
17249 };
17250 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17251 arraysize(data_writes));
17252 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17253
17254 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17255 data_writes, arraysize(data_writes));
17256 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17257
17258 // Start a request that will be throttled at start; confirm it
17259 // doesn't complete.
17260 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817261 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917262 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017263
17264 TestCompletionCallback callback;
17265 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17266 EXPECT_EQ(ERR_IO_PENDING, rv);
17267
17268 base::RunLoop().RunUntilIdle();
17269 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17270 EXPECT_FALSE(callback.have_result());
17271
17272 // Create a new request, call SetPriority on it to unthrottle,
17273 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917274 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017275 throttler->set_priority_change_closure(
17276 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17277 base::Unretained(throttler)));
17278
17279 // Start the transaction to associate a throttle with it.
17280 TestCompletionCallback callback1;
17281 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17282 EXPECT_EQ(ERR_IO_PENDING, rv);
17283
17284 trans1->SetPriority(IDLE);
17285
17286 base::RunLoop().RunUntilIdle();
17287 ASSERT_TRUE(callback.have_result());
17288 EXPECT_EQ(OK, callback.WaitForResult());
17289 ASSERT_TRUE(callback1.have_result());
17290 EXPECT_EQ(OK, callback1.WaitForResult());
17291}
17292
17293// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817294void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017295
17296// Confirm that destroying a transaction from a SetPriority call by the
17297// throttler works properly.
17298TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17299 TestNetworkStreamThrottler* throttler(nullptr);
17300 std::unique_ptr<HttpNetworkSession> session(
17301 CreateSessionWithThrottler(&session_deps_, &throttler));
17302
17303 // Send a simple request and make sure it goes through.
17304 HttpRequestInfo request;
17305 request.method = "GET";
17306 request.url = GURL("http://www.example.org/");
17307
17308 MockWrite data_writes[] = {
17309 MockWrite("GET / HTTP/1.1\r\n"
17310 "Host: www.example.org\r\n"
17311 "Connection: keep-alive\r\n\r\n"),
17312 };
17313 MockRead data_reads[] = {
17314 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17315 MockRead(SYNCHRONOUS, OK),
17316 };
17317 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17318 arraysize(data_writes));
17319 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17320
17321 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17322 data_writes, arraysize(data_writes));
17323 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17324
17325 // Start a request that will be throttled at start; confirm it
17326 // doesn't complete.
17327 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817328 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017330
17331 TestCompletionCallback callback;
17332 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17333 EXPECT_EQ(ERR_IO_PENDING, rv);
17334
17335 base::RunLoop().RunUntilIdle();
17336 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17337 EXPECT_FALSE(callback.have_result());
17338
17339 // Arrange for the set priority call on the above transaction to delete
17340 // the transaction.
bnc87dcefc2017-05-25 12:47:5817341 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017342 throttler->set_priority_change_closure(
17343 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17344
17345 // Call it and check results (partially a "doesn't crash" test).
17346 trans_ptr->SetPriority(IDLE);
17347 trans_ptr = nullptr; // No longer a valid pointer.
17348
17349 base::RunLoop().RunUntilIdle();
17350 ASSERT_FALSE(callback.have_result());
17351}
17352
nharperb7441ef2016-01-25 23:54:1417353#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117354TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417355 const std::string https_url = "https://www.example.com";
17356 HttpRequestInfo request;
17357 request.url = GURL(https_url);
17358 request.method = "GET";
17359
17360 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917361 ssl.ssl_info.token_binding_negotiated = true;
17362 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617363 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17365
bnc42331402016-07-25 13:36:1517366 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117367 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17368 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417369 MockRead(ASYNC, ERR_IO_PENDING)};
17370 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17371 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817372 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917373 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417375
17376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17377 TestCompletionCallback callback;
17378 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017379 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017380
17381 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417382
17383 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17384 HttpRequestHeaders headers;
17385 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17386 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17387}
17388#endif // !defined(OS_IOS)
17389
eustasc7d27da2017-04-06 10:33:2017390void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17391 const std::string& accept_encoding,
17392 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317393 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017394 bool should_match) {
17395 HttpRequestInfo request;
17396 request.method = "GET";
17397 request.url = GURL("http://www.foo.com/");
17398 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17399 accept_encoding);
17400
17401 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17403 // Send headers successfully, but get an error while sending the body.
17404 MockWrite data_writes[] = {
17405 MockWrite("GET / HTTP/1.1\r\n"
17406 "Host: www.foo.com\r\n"
17407 "Connection: keep-alive\r\n"
17408 "Accept-Encoding: "),
17409 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17410 };
17411
sky50576f32017-05-01 19:28:0317412 std::string response_code = "200 OK";
17413 std::string extra;
17414 if (!location.empty()) {
17415 response_code = "301 Redirect\r\nLocation: ";
17416 response_code.append(location);
17417 }
17418
eustasc7d27da2017-04-06 10:33:2017419 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317420 MockRead("HTTP/1.0 "),
17421 MockRead(response_code.data()),
17422 MockRead("\r\nContent-Encoding: "),
17423 MockRead(content_encoding.data()),
17424 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017425 MockRead(SYNCHRONOUS, OK),
17426 };
17427 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17428 arraysize(data_writes));
17429 session_deps->socket_factory->AddSocketDataProvider(&data);
17430
17431 TestCompletionCallback callback;
17432
17433 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17435
17436 rv = callback.WaitForResult();
17437 if (should_match) {
17438 EXPECT_THAT(rv, IsOk());
17439 } else {
17440 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17441 }
17442}
17443
17444TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317445 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017446}
17447
17448TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317449 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17450 true);
eustasc7d27da2017-04-06 10:33:2017451}
17452
17453TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17454 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317455 "", false);
17456}
17457
17458TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17459 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17460 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017461}
17462
xunjieli96f2a402017-06-05 17:24:2717463TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17464 ProxyConfig proxy_config;
17465 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17466 proxy_config.set_pac_mandatory(true);
17467 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917468 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Jeremy Roman0579ed62017-08-29 15:56:1917469 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417470 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717471
17472 HttpRequestInfo request;
17473 request.method = "GET";
17474 request.url = GURL("http://www.example.org/");
17475
17476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17478
17479 TestCompletionCallback callback;
17480
17481 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17483 EXPECT_THAT(callback.WaitForResult(),
17484 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17485}
17486
17487TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17488 ProxyConfig proxy_config;
17489 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17490 proxy_config.set_pac_mandatory(true);
17491 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17492 new MockAsyncProxyResolverFactory(false);
17493 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917494 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
17495 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
17496 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717497 HttpRequestInfo request;
17498 request.method = "GET";
17499 request.url = GURL("http://www.example.org/");
17500
17501 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17503
17504 TestCompletionCallback callback;
17505 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17507
17508 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17509 ERR_FAILED, &resolver);
17510 EXPECT_THAT(callback.WaitForResult(),
17511 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17512}
17513
17514TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917515 session_deps_.proxy_resolution_service =
17516 ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
xunjieli96f2a402017-06-05 17:24:2717517 session_deps_.enable_quic = false;
17518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17519
17520 HttpRequestInfo request;
17521 request.method = "GET";
17522 request.url = GURL("http://www.example.org/");
17523
17524 TestCompletionCallback callback;
17525 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17526 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17527 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17528
17529 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17530}
17531
[email protected]89ceba9a2009-03-21 03:46:0617532} // namespace net